Repository: servo/servo (language: python)

Issue:
Split up the script crate for build speed
It's by far the largest crate in terms of binary size (2.5× as big as `main`).  Building it takes almost 40 seconds and 1.8 GB resident on my machine (with debugging enabled, optimization disabled).

The various DOM types and their generated bindings mostly don't depend on each other.  We could split them among a few crates to improve compile time (especially in parallel).

Generate JS bindings in a separate crate from hand-written implementations
Based on the prior work from #21371 and the recent discussion in #1799, I have come up with a design that works for all of Servo's current WebIDL interfaces. I have yet to perform any formal benchmarks for how the build time/memory usage compares for various scenarios. I've opened this PR to make it easier to run the full testsuite and solicit feedback.

My overall goal for this PR is to replicate the work from #21371 while maintaining existing ergonomics in hand-written code in the script crate as much as possible. This largely means finding ways to minimize the use of `::<crate::DomTypeHolder>`.

If we agree on the direction of the changes, I have ideas for how to make it easier to merge in steps:
1. [x] add constructors and static functions to the generated *Methods traits (very large source of merge conflicts in this work)
2. [ ] generate more Default implementations for dictionaries automatically, removing some hand-written ones
3. [ ] move codegen and webidl files into a shared location outside of any single crate (eg. python/codegen and components/shared/webidls)
4. [ ] create new crate that is responsible for generating dictionaries/unions/enums, and move all hand-written impls for those types into the new crate
6. [ ] generate all bindings for interfaces and callbacks in the new crate

Known issues:
* [x] maplike key type is hardcoded
* [x] the principals.rs file in script_bindings is hacked up enough to compile and needs more work
* [x] the trace function in script_bindings/settings_stack.rs for StackEntry needs work
* [x] generic type interacts poorly with crown
* [x] iterator classes do not generate derive checks correctly
* [x] `ShouldNotImplDomObject` assertions are broken

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #1799
- [x] There are tests for these changes
Split up the script crate for build speed
It's by far the largest crate in terms of binary size (2.5× as big as `main`).  Building it takes almost 40 seconds and 1.8 GB resident on my machine (with debugging enabled, optimization disabled).

The various DOM types and their generated bindings mostly don't depend on each other.  We could split them among a few crates to improve compile time (especially in parallel).



Discussion / hints:
See also #925. I'm not actually convinced that they're as detached as everyone thinks; each DOM constructor calls a reflect method which takes a bindings-generated function argument, along with using generated types for things like unions/dictionaries, while all of the bindings code interacts with non-generated DOM types anytime they're used as arguments.

That is to say, I don't see a way to split it so that one crate depends on the other; there are all sorts of bidirectional dependencies that I can't see a clear way to break.

Splitting the script crate in a linear fashion may be more feasible. If we were able to move all of the generated bindings into a crate that script depends upon, that would mean that bindings and layout could build in parallel, and would reduce the working memory required to compile the rest of script. It would also speed up making changes to non-codegen parts of script.

I'd like to point out that this issue is more serious nowadays, as not only does the `script` crate totally dominate partial rebuild time (it takes several minutes for a non-optimised build now), but also the memory usage has gotten so large that it actually makes debug builds exceed the `3 GiB` virtual memory available on 32 bit systems, as reported in https://github.com/servo/servo/issues/13045 -- and it's probably just a matter of time until non-debug builds break as well...

I don't see how that would work. The generated bindings need to be able to inline the method definitions on the concrete type, and the concrete type depends fundamentally on the wrap function, and the class / JSNative definitions with it.

Latest idea from discussions with @asajeffrey:
* split generated bindings code into two crates - code that can be parameterized over FooTraits types (to avoid needing to import concrete DOM types), and code that needs to refer to the parameterized code using concrete types
* extract low-level types from script/ that the generated bindings code needs to refer to (e.g. converting native types to JS values) and put them in the generic bindings crate

This should give us the following crates:
js_bindings (generic codegen, generated types (eg. unions, dictioanries), common script/ types)
script (DOM API implementations and non-generic codegen)

This would mean that non-WebIDL/CodegenRust.py changes should not have to rebuild a significant portion of the generated bindings code.
Things that will make the above idea difficult:
* concrete DOM types in generated types (eg. unions or dictionaries containing WebIDL interface types)
At minimum, this will require collecting the list of WebIDL interfaces transitively used by a given WebIDL property (for each return value and argument), adding generic parameters for each, and propagating these generic types through layers like the union conversion methods when interacting with them.
Potential solution to the previous comment: a single trait with associated types for every WebIDL interface, and every generic method gets parameterized over the trait and uses T::Interface rather than Interface.
Or even better (?) make each FooMethods trait parametric, rather than each method inside FooMethods. Something like:

```
trait DOMTypes {
  type Foo: FooMethods<Self>;
  ...
}
trait FooMethods<DOM: DOMTypes> {
  fn bar(x: DOM::Bar) -> DOM::Baz;
  ...
}
struct DOM;
impl DOMTypes for DOM {
  type Foo = Foo;
  ...
}

struct Foo { ... }
impl FooMethods<DOM> for Foo { ... }
```
FooMethods would be unchanged. It's the standalone binding glue functions that need to be parametric.
How can FooMethods remain unchanged? Is the plan that FooMethods would be generated in the same crate as the concrete implementations? That does mean that the DOMTypes trait couldn't mention the FooMethods trait, but I don't know if that matters.
Oh right, FooMethods has arguments and return types too. Hooray!
I wonder if we can use `-> impl BarTypes` now.
We have quite a lot of places in the script crate where we assume the WebIDL method returns the concrete type, e.g. that `document.Window()` returns a `Root<Window>` not an `impl WindowMethods`.
My recommendation for how to go about this - to sort out fundamental problems quickly, I propose copying the codegen infrastructure into a new project, taking some representative WebIDL files and DOM implementations, and doing whatever it necessary to make it build unmodified. At that point the rebuild time should be _way_ smaller than Servo, which will yield much quicker feedback on experiments.
IRC conversation with @nox (initiated by @Wafflespeanut): http://logs.glob.uno/?c=mozilla%23servo&s=8+Mar+2017&e=8+Mar+2017#c626950

TL;DR:

a) splitting script is speculative, it might or might not work,
b) it might all be rendered moot by rustc improving incremental computation,
c) it would be a truck load of work, and
d) we love having this debate.
@asajeffrey b) is not entirely true: while incremental compilation *might* help with the major pain point of long build times after small changes, initial build time is also somewhat relevant; and even more importantly, it won't help with the memory usage problem.

(Maybe other compiler improvements could help with the latter, though?...)
True, I was mainly thinking about speeding up recompiling when editing DOM .rs and .webidl files. You can tell which case hurts me!
I don't think this is useful to keep this issue open. We know that splitting the script crate is something we can consider, but this will be done so far in the future (if ever) that I am hoping by then incremental compilation will make the crate size a non-issue.
@nox I want to point out, again, that incremental compilation will *not* make the memory footprint during build a non-issue.
The problem is still a real one, even if we don't have a clear vision of how to solve it, so I'd like to keep this issue open. If incremental computation makes this a non-issue, we can close the issue then.
>  Building it takes almost 40 seconds

Hahaha, the good old times
Any news on this issue ? Just having crashes by >4G memory consumption.
No news.
hmm, I'll try with kicking out stuff I dont wanna have anyways (bluetooth, gamepad, vr, ...).
unfortunately, #[cfg(...)] doesn't seem to work in many places - I really miss a real preprocessor.
Is the effort needed small, medium or xlarge?
The effort is still very large. I have proposed a [Google Summer of Code project](https://github.com/servo/servo/wiki/Prototype-ways-of-splitting-the-script-crate) to investigate the ideas we have discussed in this thread.
While trying to understand the idea, work that was already done, its problems and how associate types would be used for this I make this example:

```rust
mod script_bindings {
    // this module can be considered as forward declaratins
    // but in servo it should also contain all generated stuff from codegen (uses)
    // while actual defieinitions/implementations is outside

    pub trait TypeHolderTrait: Sized {
        type Dom: DomTrait<Self>;
        type WGPU: WgpuTrait<Self>;
    }

    // all exposed functions need to be behind trait
    // this is not a problem for webidl exposed methods
    // as the trait for them is generated by codegen
    pub trait DomTrait<TH: TypeHolderTrait> {
        fn method_on_dom(&self) -> &TH::WGPU;
    }

    pub trait WgpuTrait<TH: TypeHolderTrait> {
        fn method_on_wgpu(&self) -> &TH::Dom;
    }
}

mod script {
    use crate::script_bindings::TypeHolderTrait;
    use crate::script_bindings::DomTrait;

    pub struct ActualDom<TH: TypeHolderTrait> {
        wgpu: TH::WGPU,
    }

    /// This method is not exposed via traits,
    /// so users needs to depend on script directly
    ///
    /// See `uses_no_trait` for usage
    impl<TH: TypeHolderTrait> ActualDom<TH> {
        pub fn no_trait(&self) {

        }
    }

    impl<TH: TypeHolderTrait> DomTrait<TH> for ActualDom<TH> {
        fn method_on_dom(&self) -> &TH::WGPU {
            &self.wgpu
        }
    }

    pub fn start<TH: TypeHolderTrait>() {
        // ...
    }
}

mod script_webgpu {
    use crate::script_bindings::TypeHolderTrait;
    use crate::script_bindings::WgpuTrait;

    pub struct ActualWGPU<TH: TypeHolderTrait> {
        dom: TH::Dom,
    }

    /// Here we use associated type binding syntax to tell compiler
    /// to use script::ActualDom for Dom type
    /// this allows us to call methods on ActualDom that were not "forward declered" via traits
    impl<TH: TypeHolderTrait<Dom = crate::script::ActualDom<TH>>> ActualWGPU<TH> {
        pub fn uses_no_trait(&self) {
            self.dom.no_trait()
        }
    }

    impl<TH: TypeHolderTrait> WgpuTrait<TH> for ActualWGPU<TH> {
        fn method_on_wgpu(&self) -> &TH::Dom {
            &self.dom
        }
    }
}

/// This links implementations from script-* with "forward declarations" from script_bindings
pub struct TypeHolder;
impl script_bindings::TypeHolderTrait for TypeHolder {
    type Dom = script::ActualDom<Self>;
    type WGPU = script_webgpu::ActualWGPU<Self>;
}

fn main() {
    // when starting script we just need to put puzzle together
    script::start::<TypeHolder>();
}
```

and I must say I am thrilled. I think it should be feasible to separate codegen bindings/actual implementations and later we could even split actual implementations (see `script_webgpu`)
I'm going to try hacking together a really minimal script_bindings that uses real codegen on one interface, just to try to tease out what changes are necessary.
Well we already have https://github.com/servo/servo/pull/21371, I was thinking to go big and separate all generated code with implementations (`TypeHolderTrait` would generated by codegen). The main question I have is how to land such change (due to size).
https://github.com/servo/servo/compare/main...jdm:servo:script-split is the branch I worked on while flying on planes today. It successfully compiles with `RUSTC_BOOTSTRAP=1`; why does https://github.com/servo/servo/blob/main/components/script/lib.rs#L5 work for the script crate but fails to compile in the new script_bindings crate?

This feels promising! The codegen in script_bindings is spitting out this monster trait for my test webidl collection:
```rust
pub trait DomTypes: crate::utils::DomHelpers<Self> + Sized {
    type CSSStyleDeclaration: crate::dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::CSSStyleDeclaration>;
    type DOMException: crate::dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::DOMException>;
    type DOMParser: crate::dom::bindings::codegen::Bindings::DOMParserBinding::DOMParserMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::DOMParser>;
    type Document: crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::Document>;
    type GlobalScope: crate::dom::bindings::codegen::Bindings::GlobalScopeBinding::GlobalScopeMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::GlobalScope>;
    type Window: crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::GlobalScope> + crate::conversions::DerivedFrom<Self::Window>;
}
```
Then individual traits get parameterized like:
```rust
pub trait DOMParserMethods<D: DomTypes> {
    fn ParseFromString(&self, str: DOMString, type_: SupportedType) -> Fallible<DomRoot<D::Document>>;
    fn Constructor(global: &D::Window, proto: Option<HandleObject>) -> Result<DomRoot<D::DOMParser>, Error>;
}
```
And any bindings code that needs to interact with non-IDL methods for concrete DOM types needs to have the implementation provided by the script crate:
```rust
pub trait DomHelpers<D: crate::codegen::DomTypes::DomTypes> {
    fn throw_dom_exception(
        cx: crate::script_runtime::JSContext,
        global: &D::GlobalScope,
        result: crate::error::Error,
    );

    fn global_scope_from_object(obj: *mut JSObject) -> crate::root::DomRoot<D::GlobalScope>;

    fn global_scope_origin(global: &D::GlobalScope) -> &servo_url::MutableOrigin;
}
```
> It successfully compiles with RUSTC_BOOTSTRAP=1; why does https://github.com/servo/servo/blob/main/components/script/lib.rs#L5 work for the script crate but fails to compile in the new script_bindings crate?

Because we set `RUSTC_BOOTSTRAP` for specific crates here:
https://github.com/servo/servo/blob/2db9032e72bda6108b4eb5988eaf164141a61d64/.cargo/config.toml#L31-L33
> And any bindings code that needs to interact with non-IDL methods for concrete DOM types needs to have the implementation provided by the script crate

or use associated type binding syntax as shown above (will be needed for every consumer, so this is not appropriate for very used methods).
> > And any bindings code that needs to interact with non-IDL methods for concrete DOM types needs to have the implementation provided by the script crate
> 
> or use associated type binding syntax as shown above (will be needed for every consumer, so this is not appropriate for very used methods).

For non-IDL methods that are impl on concrete DOM types we can use specific traits for for concrete DOM types (ex: `GlobalScopeHelpers` that would be implemented on `GlobalScope`), to add this to traits that are impl on `DomTypes::GlobalScope`, we can use new Bindings.conf field:
```conf
'GlobalScope': {
    'traits': ['GlobalScopeHelpers'],
},
```
and user will have to manually define it in core script crate:
```rust
pub trait GlobalScopeHelpers<D: crate::codegen::DomTypes::DomTypes<GlobalScope = Self>> {
    fn global_scope_from_object(obj: *mut JSObject) -> DomRoot<Self>;

    fn global_scope_origin(global: &Self) -> &servo_url::MutableOrigin;
}
```

functions that are not methods should simply be defined in core script with generic arg `throw_dom_exception<D: DomTypes>(...)`.
I have created a document with all stuff in one place (and some more ideas) on how to do this: https://gist.github.com/sagudev/c4a029cfccda9553adac32749a9ba583
I am working on getting the script_bindings crate in my branch compiling with all real webidl files present. It's going surprisingly well so far.
> I am working on getting the script_bindings crate in my branch compiling with all real webidl files present. It's going surprisingly well so far.

I was actually planing to do this, after I make sure that we can also measure runtime performance, hence my work on speedometer.
My script_bindings crate is now compiling with all DOM interfaces present \o/ Next step is getting the script crate to use tho generated bindings. https://github.com/jdm/servo/tree/script-split has all the latest changes.
I've made good progress in that branch, and I've found ways to make the changes in script/ minimally invasive, but I'm now running into errors that make no sense and feel like some kind of compiler bug. There are thousands of errors where the compiler can't resolve normal impl method calls, and it's hard to figure out how to narrow down what's going on.
Like, seriously. What is going on here?
```
error[E0599]: no method named `chars` found for reference `&str` in the current scope
   --> components/script/textinput.rs:247:19
    |
247 |     for c in text.chars() {
    |                   ^^^^^
    |
    = help: items from traits can only be used if the trait is in scope
help: trait `TextSource` which provides `chars` is implemented but not in scope; perhaps you want to import it
    |
7   + use unicode_bidi::TextSource;
    |
help: there is a method `par_chars` with a similar name
    |
247 |     for c in text.par_chars() {
    |                   ~~~~~~~~~
```
let me try
I got:
```
servo/target/debug/build/script-607bfb53410c9870/out/InterfaceTypes.rs: No such file or directory (os error 2)
   --> components/script/dom/mod.rs:209:5
    |
209 |     include!(concat!(env!("OUT_DIR"), "/InterfaceTypes.rs"));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in the macro `include` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `script` (lib) due to 1 previous error
```
on https://github.com/jdm/servo/commit/b05a845b3881f287907be101d9363b7d3500f37f. So you might need to run `mach clean` to make sure rust is not using old generated files.
Same errors after addressing that.
Usually it's good idea to start looking at first errors and fixing them first (as those can cause more false errors later).

For me these are error due to orphaning rules:
```
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/bluetoothuuid.rs:627:1
    |
627 | impl Clone for StringOrUnsignedLong {
    | ^^^^^^^^^^^^^^^--------------------
    | |              |
    | |              `script_bindings::codegen::UnionTypes::StringOrUnsignedLong` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> components/script/dom/gpucanvascontext.rs:42:1
   |
42 | impl Clone for GPUCanvasConfiguration {
   | ^^^^^^^^^^^^^^^----------------------
   | |              |
   | |              `script_bindings::codegen::Bindings::WebGPUBinding::GPUCanvasConfiguration` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> components/script/dom/gpucanvascontext.rs:54:1
   |
54 | impl Clone for HTMLCanvasElementOrOffscreenCanvas {
   | ^^^^^^^^^^^^^^^----------------------------------
   | |              |
   | |              `script_bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/request.rs:876:1
    |
876 | impl Clone for HeadersInit {
    | ^^^^^^^^^^^^^^^-----------
    | |              |
    | |              `script_bindings::codegen::UnionTypes::ByteStringSequenceSequenceOrByteStringByteStringRecord` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> components/script/dom/gpucanvascontext.rs:63:1
   |
63 | impl malloc_size_of::MallocSizeOf for GPUTextureDescriptor {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------
   | |                                     |
   | |                                     `script_bindings::codegen::Bindings::WebGPUBinding::GPUTextureDescriptor` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> components/script/dom/gpucanvascontext.rs:86:1
   |
86 | impl malloc_size_of::MallocSizeOf for HTMLCanvasElementOrOffscreenCanvas {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------
   | |                                     |
   | |                                     `script_bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/security_manager.rs:170:1
    |
170 | impl Serialize for SecurityPolicyViolationEventDisposition {
    | ^^^^^^^^^^^^^^^^^^^---------------------------------------
    | |                  |
    | |                  `SecurityPolicyViolationEventDisposition` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/audiobuffersourcenode.rs:264:1
    |
264 | impl<'a> From<&'a AudioBufferSourceOptions> for AudioBufferSourceNodeOptions {
    | ^^^^^^^^^----------------------------------^^^^^----------------------------
    | |        |                                      |
    | |        |                                      `AudioBufferSourceNodeOptions` is not defined in the current crate
    | |        `script_bindings::codegen::Bindings::AudioBufferSourceNodeBinding::AudioBufferSourceOptions` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/audionode.rs:370:1
    |
370 | impl From<ChannelCountMode> for ServoMediaChannelCountMode {
    | ^^^^^----------------------^^^^^--------------------------
    | |    |                          |
    | |    |                          `servo_media::servo_media_audio::node::ChannelCountMode` is not defined in the current crate
    | |    `script_bindings::codegen::Bindings::AudioNodeBinding::ChannelCountMode` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/audionode.rs:380:1
    |
380 | impl From<ChannelInterpretation> for ServoMediaChannelInterpretation {
    | ^^^^^---------------------------^^^^^-------------------------------
    | |    |                               |
    | |    |                               `servo_media::servo_media_audio::node::ChannelInterpretation` is not defined in the current crate
    | |    `script_bindings::codegen::Bindings::AudioNodeBinding::ChannelInterpretation` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/audioparam.rs:325:1
    |
325 | impl From<AutomationRate> for ParamRate {
    | ^^^^^--------------------^^^^^---------
    | |    |                        |
    | |    |                        `ParamRate` is not defined in the current crate
    | |    `AutomationRate` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/baseaudiocontext.rs:591:1
    |
591 | impl From<ProcessingState> for AudioContextState {
    | ^^^^^---------------------^^^^^-----------------
    | |    |                         |
    | |    |                         `AudioContextState` is not defined in the current crate
    | |    `ProcessingState` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
```

is 
```
error[E0599]: no method named `chars` found for reference `&str` in the current scope
``` 
your first error?
No, I've been skipping over those orphan rule violations because I understand them. I have not found going top to bottom to be the most useful strategy so far.
> I have not found going top to bottom to be the most useful strategy so far.

Well, it the most sure ways to fix proper error properly. I got burnt few times from fixing wrong errors at wrong time.
My branch now a) compiles, b) opens pages that don't use any JS. I know what's missing that should get JS working as well.
🔨 Triggering try run ([#10824104510](https://github.com/servo/servo/actions/runs/10824104510)) for Linux WPT
⚠️ Try run ([#10824104510](https://github.com/servo/servo/actions/runs/10824104510)) failed.
Hm, I think the error comes from the way we use reuse git checkout on self hosted runners. I suggest running CI in your own fork via `mach try wpt-2020` and linking result here.

EDIT: Or maybe not given that https://github.com/jdm/servo/actions/runs/10823932638 fails too.
🔨 Triggering try run ([#10824254602](https://github.com/servo/servo/actions/runs/10824254602)) for Linux WPT
⚠️ Try run ([#10824254602](https://github.com/servo/servo/actions/runs/10824254602)) failed.
I'll see if https://github.com/jdm/servo/actions/runs/10824430930 is able to make better progress.
data clone errors are due to hacks in principals.rs
https://github.com/jdm/servo/actions/runs/10887236429
Only one last test result to investigate!
```
▶ OK [expected CRASH] /dom/nodes/insertion-removing-steps/blur-event.window.html
  │   ▶ FAIL [expected PASS] <input> element does not fire blur event upon DOM removal
  │   │   → assert_false: Blur event was not fired expected false got true
  │   │ 
  │   │ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:8:15
  │   │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2622:25
  │   │ test@http://web-platform.test:8000/resources/testharness.js:633:30
  │   └ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:1:5
  │   ▶ FAIL [expected PASS] <button> element does not fire blur/focusout events upon DOM removal
  │   │   → assert_false: Blur event was not fired expected false got true
  │   │ 
  │   │ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:25:15
  │   │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2622:25
  │   │ test@http://web-platform.test:8000/resources/testharness.js:633:30
  └   └ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:11:5
```
> Only one last test result to investigate!
> 
> ```
> ▶ OK [expected CRASH] /dom/nodes/insertion-removing-steps/blur-event.window.html
>   │   ▶ FAIL [expected PASS] <input> element does not fire blur event upon DOM removal
>   │   │   → assert_false: Blur event was not fired expected false got true
>   │   │ 
>   │   │ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:8:15
>   │   │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2622:25
>   │   │ test@http://web-platform.test:8000/resources/testharness.js:633:30
>   │   └ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:1:5
>   │   ▶ FAIL [expected PASS] <button> element does not fire blur/focusout events upon DOM removal
>   │   │   → assert_false: Blur event was not fired expected false got true
>   │   │ 
>   │   │ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:25:15
>   │   │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2622:25
>   │   │ test@http://web-platform.test:8000/resources/testharness.js:633:30
>   └   └ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:11:5
> ```

Might be flake, so be sure to rule that out first.
> ShouldNotImplDomObject assertions are broken

I guess the problem here is that we do this check using trait shenanigans and orphan rules bit us hard, but we can port inheritance_integrity back to crown: https://github.com/servo/servo/pull/15567 or try to fix `ShouldNotImplDomObject` by using supertrait or something. 
> Only one last test result to investigate!
> 
> ```
> ▶ OK [expected CRASH] /dom/nodes/insertion-removing-steps/blur-event.window.html
>   │   ▶ FAIL [expected PASS] <input> element does not fire blur event upon DOM removal
>   │   │   → assert_false: Blur event was not fired expected false got true
>   │   │ 
>   │   │ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:8:15
>   │   │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2622:25
>   │   │ test@http://web-platform.test:8000/resources/testharness.js:633:30
>   │   └ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:1:5
>   │   ▶ FAIL [expected PASS] <button> element does not fire blur/focusout events upon DOM removal
>   │   │   → assert_false: Blur event was not fired expected false got true
>   │   │ 
>   │   │ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:25:15
>   │   │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:2622:25
>   │   │ test@http://web-platform.test:8000/resources/testharness.js:633:30
>   └   └ @http://web-platform.test:8000/dom/nodes/insertion-removing-steps/blur-event.window.js:11:5
> ```

Aha, this is because I commented out a line in callback.rs that fails an assertion in that test (#32972): https://github.com/servo/servo/pull/33416/files#diff-ebc3f2cee053bcf3b0d2fae9c56e2a052fc1400813e65c8abfbb31a521fdc61cR248-R249
First benchmarks for build times, using 2022 apple MacBook Air m2, 8gb, 8cpu, based on 0e56241c1be52efd52e7ba4c999fec0bf29ce2de:

Debug builds:

|     | main | branch |
| --- | --- | --- |
|clean| 3m19s | 3m13s |
|incremental, webidl + impl | 43s | 40s
|incremental, impl | 36s | 22s

Release builds:

|        | main | branch |
| --- | --- | --- |
| clean| 5m20s | 5m41s |
| incremental, webidl + impl | 1m26s | 1m32s
| incremental, impl | 1m26s | 1m07s

Testing methadology:
1. `rm -rf target/ && ./mach build [-r]`
2. open `WebGLRenderingContext.webidl` (under components/script/Dom/webidls on main and components/script_bindings/webidls on branch) and add a new `undefined whatever();`, then add `fn Whatever(&self) {}` to the corresponding impl in `webglrenderingcontext.rs`, then build
3.  add a `fn foo(&self) {}` to the `impl Capabilities` block in `webglrenderingcontext.rs`, then build

I used the build time reported by cargo for each measurement.

In the ideal case (only touching a source file in script/), for this particular machine, these changes save 15-20s during an incremental build.
> open WebGLRenderingContext.webidl and add a new undefined whatever();, then add fn Whatever(&self) {} to the corresponding impl in webglrenderingcontext.rs, then build

```patch
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 51bde8adeb..555ffc333a 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -1958,6 +1958,7 @@ impl Drop for WebGLRenderingContext {
 }
 
 impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContext {
+    fn Whatever(&self) {}
     // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
     fn Canvas(&self) -> DomRoot<HTMLCanvasElement> {
         DomRoot::from_ref(&*self.canvas)
diff --git a/components/script_bindings/webidls/WebGLRenderingContext.webidl b/components/script_bindings/webidls/WebGLRenderingContext.webidl
index fcd3f9752a..a1e19342d6 100644
--- a/components/script_bindings/webidls/WebGLRenderingContext.webidl
+++ b/components/script_bindings/webidls/WebGLRenderingContext.webidl
@@ -683,6 +683,7 @@ interface mixin WebGLRenderingContextOverloads
 [Exposed=(Window)]
 interface WebGLRenderingContext
 {
+    undefined whatever();
 };
 WebGLRenderingContext includes WebGLRenderingContextBase;
 WebGLRenderingContext includes WebGLRenderingContextOverloads;
```

> add a fn foo(&self) {} to the impl Capabilities block in webglrenderingcontext.rs, then build

```patch
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 555ffc333a..96931cf65c 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -4688,6 +4688,8 @@ struct Capabilities {
 }
 
 impl Capabilities {
+    fn foo(&self) {}
+    
     fn set(&self, cap: u32, set: bool) -> WebGLResult<bool> {
         let cap = CapFlags::from_enum(cap)?;
         let mut value = self.value.get();
```

Fedora 40 on a Ryzen 7 3700X, 8 cores with 32gb ram, comparing https://github.com/servo/servo/commit/0e56241c1be52efd52e7ba4c999fec0bf29ce2de with https://github.com/servo/servo/pull/33416/commits/858f88d2312a91d6c0c8274c9f2cbf132309dd4b.

# Debug
| | main | branch |
| --- | --- | --- |
| clean | 03:47/03:37 | 03:55 |
| incremental, webidl + impl | 01:22 | 01:15 |
| incremental, impl | 01:05 | 00:56 |

# Release
| | main | branch |
| --- | --- | --- |
| clean | 05:36 | 04:39 |
| incremental, webidl + impl | 01:53 | 01:49 |
| incremental, impl | 01:53 | 01:12 |

(The results seem a bit odd, I might rerun them later)
Probably benchmarking `production` is also interesting, since that is where the long build-time of script is really noticable, due to `codegen-units = 1`.
NixOS 24.05,  Intel i7-12800HX (24 threads, 8p + 8e cores), 64GB RAM 


# Debug

|            | main    | branch
|------------|---------|---------
|clean                      | 2m 30s  | 2m 36s
|incremental, webidl + impl | 0m 46s  | 0m 40s
|incremental, impl          | 0m 38s  | 0m 30s

# Release

|            | main    | branch |
|------------|---------|---------
|clean                      | 3m 37s  | 3m 27s |
|incremental, webidl + impl | 1m 19s  | 1m 15s |
|incremental, impl          | 1m 18s  | 0m 50s |


# Production

|            | main    | branch
|------------|---------|---------
|clean                      | 5m 52s | 5m 32s
|incremental, webidl + impl | 4m 10s | 3m 54s
|incremental, impl          | 4m 11s | 3m 31s

Ubuntu 24.04,  AMD Ryzen 7 PRO 5875U (16 threads, 8 cores), 16GB RAM (laptop)

I also unset `CCACHE` that I usually use.


# Debug

|            | main    | branch
|------------|---------|---------
|clean                      | 4m 35s  | 5m 24s
|incremental, webidl + impl | 0m 58s  | 0m 47s
|incremental, impl          | 0m 45s  | 0m 27s

# Release

|            | main    | branch |
|------------|---------|---------
|clean                      | 8m 8s  | 7m 20s |
|incremental, webidl + impl | 2m 14s  | 1m 55s |
|incremental, impl          | 2m 6s  | 1m 25s |


# Production

|            | main    | branch
|------------|---------|---------
|clean                      | 10m 46s |9m 47s
|incremental, webidl + impl | 6m 0s | 5m 1s
|incremental, impl          | 6m 7s | 4m 27s


I also stored all [cargo-timings in zip](https://github.com/user-attachments/files/17071792/cargo-timings.zip) and I must say graphs are interesting! One noticeable thing is that we avoid reruning build.rs of script crate (although it's quick as we have some webidl caching on python level too), but this should not run at all if we do not change any webidl file (we are missing [`rerun-if-changed`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed) as by default whole crate is checked for change).

EDIT: Opened https://github.com/servo/servo/pull/33502 for rerun-if-changed in script/build.rs

This seems like a great change. I am wondering if it would be possible to get further benefits (both compile time speed ups, and modularity) by splitting the script crate "horizontally" (i.e. having each set of APIs in their own crate). I imagine there's a core set of APIs that would need to all be compiled together, but many web APIs are quite independent and naively I might expect those to be compilable independently.
> This seems like a great change. I am wondering if it would be possible to get further benefits (both compile time speed ups, and modularity) by splitting the script crate "horizontally" (i.e. having each set of APIs in their own crate). I imagine there's a core set of APIs that would need to all be compiled together, but many web APIs are quite independent and naively I might expect those to be compilable independently.

This should also be possible, after this lands. See #1799 and https://gist.github.com/sagudev/c4a029cfccda9553adac32749a9ba583#stage-2
I'm planning to move ahead with this work, following the path I outlined in the initial PR description to reduce the risk of rebase conflicts and making overall changes easier to review. The first step will be making the generated Methods traits contain static methods and special operations, which should be a boring but independently useful change.
> I'm planning to move ahead with this work, following the path I outlined in the initial PR description to reduce the risk of rebase conflicts and making overall changes easier to review.

+1 for that, but we should also work on resolving issues before major landing (step 5).
I will also try to fix crown problem.
I tried to extract problem with `DecodeSuccessCallback` that uses `allow_unrooted_interior` but this doesn't compile (although similar code compiles in servo):

```rust
#[crown::unrooted_must_root_lint::allow_unrooted_interior]
struct Outer {
    inner: Inner2,
}

#[crown::unrooted_must_root_lint::must_root]
struct Inner2;
```

am I misunderstanding `allow_unrooted_interior`? Unfortunately there are no test/docs for `allow_unrooted_interior` that I could look at.
We have https://github.com/servo/servo/blob/c7a4e4f627f0bf331cedc1700ddeb92ffcba4e78/components/script/dom/bindings/mod.rs#L172-L175
@jdm why script crate still have build.rs and https://github.com/jdm/servo/blob/ce640c6730d1379dbd2bc3688b79875f274aaf50/components/script/dom/bindings/mod.rs#L188?
Crown would be problematic as currently this does not raise error:
```rust
#[crown::unrooted_must_root_lint::must_root]
struct Foo(i32);
struct Bar<TH: TypeHolderTrait>(TH::F);
//~^ ERROR: Type must be rooted, use #[crown::unrooted_must_root_lint::must_root] on the struct definition to propagate

trait TypeHolderTrait {
    type F;
    type B;
}

struct TypeHolder;

impl TypeHolderTrait for TypeHolder {
    type F = Foo;
    type B = Bar<Self>;
}

fn main() {}
```

per https://github.com/fan-tom/liquid-rust:

> We can easily get MIR of function or constexpr if we know substitution of all type variables within that fun/const. It means however that we cannot analyze generic functions in abstract, only when they are called from monomorphized function

I think it is possible to lower HIR to MIR in LatePass: https://github.com/rust-lang/rust-clippy/blob/master/clippy_utils/src/mir/mod.rs#L134
relevant issue that try to write MIR lint (when MirPass was still available): https://github.com/servo/servo/issues/14902

Both rooting and tracing concept are actually very similar. All (there are some exceptions) types that contain must_root types must be must_root too and same goes for Traceables, so if we can unify concepts and lints for them that would be ideal (we can model must_root with "marker" Trait).


I think we can only get MIR for bodies (function, closures); maybe the fastest option would be to make crown enforce something like this:
```rust
#[crown::unrooted_must_root_lint::must_root]
struct Foo(i32);
struct Bar<TH: TypeHolderTrait>(TH::F);
//~^ ERROR: Type must be rooted, use #[crown::unrooted_must_root_lint::must_root] on the struct definition to propagate
struct Baz(i32);

trait TypeHolderTrait {
    #[crown::unrooted_must_root_lint::must_root]
    type F;
    type FF;
    type B;
    #[crown::unrooted_must_root_lint::must_root]
    type BB;
}

struct TypeHolder;

impl TypeHolderTrait for TypeHolder {
    #[crown::unrooted_must_root_lint::must_root]
    type F = Foo;
    type FF = Foo;
    //~^ ERROR: Type must be rooted, use #[crown::unrooted_must_root_lint::must_root] on the type definition to propagate
    type B = Bar<Self>;
    type VV = Bar;
    //~^ ERROR: Type must be rooted, use #[crown::unrooted_must_root_lint::must_root] on the type definition to propagate
}
```
> @jdm why script crate still have build.rs and https://github.com/jdm/servo/blob/ce640c6730d1379dbd2bc3688b79875f274aaf50/components/script/dom/bindings/mod.rs#L188?

We still generate some code via script's build script when the actual concrete DOM types are available. For example, the implementation of the DOM types trait that's generated in script_bindings.
> > @jdm why script crate still have build.rs and https://github.com/jdm/servo/blob/ce640c6730d1379dbd2bc3688b79875f274aaf50/components/script/dom/bindings/mod.rs#L188?
> 
> We still generate some code via script's build script when the actual concrete DOM types are available. For example, the implementation of the DOM types trait that's generated in script_bindings.

I think we should just generate this once as part of script_bindings, then include! macro to import it. 
Hmm, interesting idea. I'll think about that!
I tried applying https://github.com/servo/servo/pull/34163, but it didn't create any additional errors in script crate.
> I tried applying #34163, but it didn't create any additional errors in script crate.

I'm building on #34163 and addressing the errors. I've got some more fixes for crown that will be needed.
Huh, it's weird that I can't reproduce the unit test failure locally with `./mach test-unit`.
I'll try rebasing.
> I'll try rebasing.

This will be hard.
Btw instead of updating rust version just port https://github.com/servo/servo/pull/34257
Mmm, looks like the test failures are triggered by the rust upgrade: https://github.com/servo/servo/pull/34270
🔨 Triggering try run ([#11887566161](https://github.com/servo/servo/actions/runs/11887566161)) for Linux WPT
<span>Test results for linux-wpt-layout-2020 from try job ([#11887566161](https://github.com/servo/servo/actions/runs/11887566161)):<div><details><summary>Flaky unexpected result (24)</summary><ul><li><span>TIMEOUT [expected OK] `/_webgl/conformance/glsl/misc/shader-uniform-packing-restrictions.html` ([#28103](http://github.com/servo/servo/issues/28103))</span></li><li><span>TIMEOUT [expected OK] `/_webgl/conformance/reading/read-pixels-test.html`</span></li><li><span>OK `/_webgl/conformance/textures/misc/texture-video-transparent.html` ([#34127](http://github.com/servo/servo/issues/34127))</span><ul><li><span>FAIL [expected PASS] subtest: `WebGL test #8: right is blue, but: at (4, 4) expected: 255,0,0 was 0,0,0
0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255` 
```
assert_true: right is blue, but: at (4, 4) expected: 255,0,0 was 0,0,0
0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255 expected true got false
```
</span></li><li><span>FAIL [expected PASS] subtest: `WebGL test #9: right is blue, but: at (4, 4) expected: 255,0,0 was 0,0,0
0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255` 
```
assert_true: right is blue, but: at (4, 4) expected: 255,0,0 was 0,0,0
0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255 expected true got false
```
</span></li></ul></li><li><span>TIMEOUT [expected OK] `/_webgl/conformance/uniforms/out-of-bounds-uniform-array-access.html` ([#26225](http://github.com/servo/servo/issues/26225))</span><ul><li><span>NOTRUN [expected PASS] subtest: `Overall test`</span></li></ul></li><li><span>PASS [expected FAIL] `/css/compositing/mix-blend-mode/mix-blend-mode-video-sibling.html` ([#32849](http://github.com/servo/servo/issues/32849))</span></li><li><span>TIMEOUT [expected OK] `/css/css-flexbox/abspos/position-absolute-013.html`</span></li><li><span>OK `/css/css-values/cap-invalidation.html` ([#32757](http://github.com/servo/servo/issues/32757))</span><ul><li><span>FAIL [expected PASS] subtest: `CSS Values and Units Test: cap invalidation` 
```
uncaught exception: Error: assert_not_equals: expect the capital height of Ahem and sans-serif to be different got disallowed value 371.3333333333333
```
</span></li></ul></li><li><span>CRASH [expected OK] `/encoding/legacy-mb-japanese/euc-jp/eucjp-decode-x-euc-jp.html?1001-2000`</span></li><li><span>CRASH [expected OK] `/encoding/legacy-mb-tchinese/big5/big5-decode.html?13001-14000` ([#34184](http://github.com/servo/servo/issues/34184))</span></li><li><span>OK `/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html` ([#29048](http://github.com/servo/servo/issues/29048))</span><ul><li><span>FAIL [expected PASS] subtest: `Navigating to a different document with location.href` 
```
assert_equals: expected "http://web-platform.test:8000/common/blank.html?1" but got "about:blank"
```
</span></li></ul></li><li><span>OK `/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html` ([#28066](http://github.com/servo/servo/issues/28066))</span><ul><li><span>FAIL [expected PASS] subtest: `0041 set in href="" targeting a frame and clicked` 
```
assert_equals: expected "A" but got ""
```
</span></li><li><span>FAIL [expected PASS] subtest: `0080 00FF set in href="" targeting a frame and clicked` 
```
assert_equals: expected "ÿ" but got ""
```
</span></li><li><span>FAIL [expected PASS] subtest: `0080 00FF 0100 set in href="" targeting a frame and clicked` 
```
assert_equals: expected "ÿĀ" but got ""
```
</span></li><li><span>FAIL [expected PASS] subtest: `D83D DE0D set in href="" targeting a frame and clicked` 
```
assert_equals: expected "😍" but got ""
```
</span></li><li><span>FAIL [expected PASS] subtest: `DE0D 0041 set in href="" targeting a frame and clicked` 
```
assert_equals: expected "\ufffdA" but got ""
```
</span></li></ul></li><li><span>OK `/html/browsers/history/the-history-interface/traverse_the_history_2.html` ([#21383](http://github.com/servo/servo/issues/21383))</span><ul><li><span>PASS [expected FAIL] subtest: `Multiple history traversals, last would be aborted`</span></li></ul></li><li><span>TIMEOUT [expected OK] `/html/browsers/origin/cross-origin-objects/cross-origin-objects.html` ([#28569](http://github.com/servo/servo/issues/28569))</span></li><li><span>OK `/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-reload-location-reload.html` ([#32595](http://github.com/servo/servo/issues/32595))</span><ul><li><span>PASS [expected FAIL] subtest: `Reloading iframe loading='lazy' before it is loaded: location.reload`</span></li></ul></li><li><span>TIMEOUT [expected CRASH] `/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html` ([#22154](http://github.com/servo/servo/issues/22154))</span></li><li><span>OK [expected TIMEOUT] `/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html` ([#24066](http://github.com/servo/servo/issues/24066))</span><ul><li><span>FAIL [expected NOTRUN] subtest: `Check that popups from a sandboxed iframe do not escape the sandbox` 
```
assert_equals: It came from a sandboxed iframe expected "null" but got "http://web-platform.test:8000"
```
</span></li></ul></li><li><span>OK `/html/semantics/embedded-content/the-img-element/non-active-document.html` ([#21544](http://github.com/servo/servo/issues/21544))</span><ul><li><span>FAIL [expected PASS] subtest: `DOMParser` 
```
assert_unreached: got unexpected load event Reached unreachable code
```
</span></li></ul></li><li><span>CRASH [expected OK] `/html/semantics/forms/the-fieldset-element/disabled-003.html` ([#31730](http://github.com/servo/servo/issues/31730))</span></li><li><span>OK `/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html` ([#23205](http://github.com/servo/servo/issues/23205))</span><ul><li><span>PASS [expected FAIL] subtest: `Check that rel=noopener with target=_self does a normal load`</span></li></ul></li><li><span>OK `/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.worker.html` ([#33909](http://github.com/servo/servo/issues/33909))</span><ul><li><span>FAIL [expected PASS] subtest: `Revoking a blob URL immediately after calling import will not fail` 
```
promise_test: Unhandled rejection with value: object "TypeError: Dynamic import failed"
```
</span></li></ul></li><li><span>OK `/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html` ([#26243](http://github.com/servo/servo/issues/26243))</span><ul><li><span>FAIL [expected PASS] subtest: `document.write in an imported module` 
```
assert_true: onload must be called expected true got false
```
</span></li></ul></li><li><span>TIMEOUT [expected OK] `/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.html` ([#26371](http://github.com/servo/servo/issues/26371))</span><ul><li><span>TIMEOUT [expected FAIL] subtest: `delayed handling: delaying handling rejected promise created from createImageBitmap will cause both events to fire` 
```
Test timed out
```
</span></li></ul></li><li><span>TIMEOUT `/resource-timing/nested-context-navigations-iframe.html` ([#24311](http://github.com/servo/servo/issues/24311))</span><ul><li><span>PASS [expected TIMEOUT] subtest: `Test that iframe navigations are not observable by the parent, even after history navigations by the parent`</span></li><li><span>TIMEOUT [expected NOTRUN] subtest: `Test that crossorigin iframe navigations are not observable by the parent, even after history navigations by the parent` 
```
Test timed out
```
</span></li></ul></li><li><span>ERROR [expected OK] `/workers/constructors/Worker/Worker-constructor.html` ([#22991](http://github.com/servo/servo/issues/22991))</span></li></ul></details><details><summary>Stable unexpected results that are known to be intermittent (7)</summary><ul><li><span>TIMEOUT `/FileAPI/url/url-in-tags-revoke.window.html` ([#19978](http://github.com/servo/servo/issues/19978))</span><ul><li><span>TIMEOUT [expected PASS] subtest: `Fetching a blob URL immediately before revoking it works in &lt;script&gt; tags.` 
```
Test timed out
```
</span></li></ul></li><li><span>FAIL [expected PASS] `/_mozilla/css/iframe/hide_and_show.html` ([#15265](http://github.com/servo/servo/issues/15265))</span></li><li><span>TIMEOUT `/fetch/metadata/generated/element-img-environment-change.https.sub.html` ([#30111](http://github.com/servo/servo/issues/30111))</span><ul><li><span>FAIL [expected PASS] subtest: `sec-fetch-site - Same origin, no attributes` 
```
promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
```
</span></li></ul></li><li><span>OK `/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin-fragment.html` ([#20768](http://github.com/servo/servo/issues/20768))</span><ul><li><span>PASS [expected FAIL] subtest: `Tests that a fragment navigation in the unload handler will not block the initial navigation`</span></li></ul></li><li><span>TIMEOUT [expected CRASH] `/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html` ([#24057](http://github.com/servo/servo/issues/24057))</span><ul><li><span>TIMEOUT [expected FAIL] subtest: `Check that popups from a sandboxed iframe escape the sandbox if
       allow-popups-to-escape-sandbox is used` 
```
Test timed out
```
</span></li></ul></li><li><span>OK [expected TIMEOUT] `/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html` ([#24066](http://github.com/servo/servo/issues/24066))</span></li><li><span>OK [expected ERROR] `/webxr/render_state_update.https.html` ([#27535](http://github.com/servo/servo/issues/27535))</span></li></ul></details></div></span>
✨ Try run ([#11887566161](https://github.com/servo/servo/actions/runs/11887566161)) succeeded.
All the known issues now have solutions. I think we can start figuring out:
1. the name of the new crate
2. where to move the codegen and webidl files
3. how to review the changes/how to make the changes easier to review
> the name of the new crate

I think `script_bindings` is a good name.

> move codegen and webidl files into a shared location outside of any single crate (eg. python/codegen and components/shared/webidls)

I am not sure how I feel about separating webidl/codegen, it would make sense to remain as part of script_*. I think we can start by creating script_bindings that has build.rs, codegen and webidls, and all of is files are simply `include!` from script.

> how to review the changes/how to make the changes easier to review

Crown changes would also make sense to split into separate PR, as for others I am not sure how easy would be to split them.
See also #925. I'm not actually convinced that they're as detached as everyone thinks; each DOM constructor calls a reflect method which takes a bindings-generated function argument, along with using generated types for things like unions/dictionaries, while all of the bindings code interacts with non-generated DOM types anytime they're used as arguments.

That is to say, I don't see a way to split it so that one crate depends on the other; there are all sorts of bidirectional dependencies that I can't see a clear way to break.

Splitting the script crate in a linear fashion may be more feasible. If we were able to move all of the generated bindings into a crate that script depends upon, that would mean that bindings and layout could build in parallel, and would reduce the working memory required to compile the rest of script. It would also speed up making changes to non-codegen parts of script.

I'd like to point out that this issue is more serious nowadays, as not only does the `script` crate totally dominate partial rebuild time (it takes several minutes for a non-optimised build now), but also the memory usage has gotten so large that it actually makes debug builds exceed the `3 GiB` virtual memory available on 32 bit systems, as reported in https://github.com/servo/servo/issues/13045 -- and it's probably just a matter of time until non-debug builds break as well...

I don't see how that would work. The generated bindings need to be able to inline the method definitions on the concrete type, and the concrete type depends fundamentally on the wrap function, and the class / JSNative definitions with it.

Latest idea from discussions with @asajeffrey:
* split generated bindings code into two crates - code that can be parameterized over FooTraits types (to avoid needing to import concrete DOM types), and code that needs to refer to the parameterized code using concrete types
* extract low-level types from script/ that the generated bindings code needs to refer to (e.g. converting native types to JS values) and put them in the generic bindings crate

This should give us the following crates:
js_bindings (generic codegen, generated types (eg. unions, dictioanries), common script/ types)
script (DOM API implementations and non-generic codegen)

This would mean that non-WebIDL/CodegenRust.py changes should not have to rebuild a significant portion of the generated bindings code.
Things that will make the above idea difficult:
* concrete DOM types in generated types (eg. unions or dictionaries containing WebIDL interface types)
At minimum, this will require collecting the list of WebIDL interfaces transitively used by a given WebIDL property (for each return value and argument), adding generic parameters for each, and propagating these generic types through layers like the union conversion methods when interacting with them.
Potential solution to the previous comment: a single trait with associated types for every WebIDL interface, and every generic method gets parameterized over the trait and uses T::Interface rather than Interface.
Or even better (?) make each FooMethods trait parametric, rather than each method inside FooMethods. Something like:

```
trait DOMTypes {
  type Foo: FooMethods<Self>;
  ...
}
trait FooMethods<DOM: DOMTypes> {
  fn bar(x: DOM::Bar) -> DOM::Baz;
  ...
}
struct DOM;
impl DOMTypes for DOM {
  type Foo = Foo;
  ...
}

struct Foo { ... }
impl FooMethods<DOM> for Foo { ... }
```
FooMethods would be unchanged. It's the standalone binding glue functions that need to be parametric.
How can FooMethods remain unchanged? Is the plan that FooMethods would be generated in the same crate as the concrete implementations? That does mean that the DOMTypes trait couldn't mention the FooMethods trait, but I don't know if that matters.
Oh right, FooMethods has arguments and return types too. Hooray!
I wonder if we can use `-> impl BarTypes` now.
We have quite a lot of places in the script crate where we assume the WebIDL method returns the concrete type, e.g. that `document.Window()` returns a `Root<Window>` not an `impl WindowMethods`.
My recommendation for how to go about this - to sort out fundamental problems quickly, I propose copying the codegen infrastructure into a new project, taking some representative WebIDL files and DOM implementations, and doing whatever it necessary to make it build unmodified. At that point the rebuild time should be _way_ smaller than Servo, which will yield much quicker feedback on experiments.
IRC conversation with @nox (initiated by @Wafflespeanut): http://logs.glob.uno/?c=mozilla%23servo&s=8+Mar+2017&e=8+Mar+2017#c626950

TL;DR:

a) splitting script is speculative, it might or might not work,
b) it might all be rendered moot by rustc improving incremental computation,
c) it would be a truck load of work, and
d) we love having this debate.
@asajeffrey b) is not entirely true: while incremental compilation *might* help with the major pain point of long build times after small changes, initial build time is also somewhat relevant; and even more importantly, it won't help with the memory usage problem.

(Maybe other compiler improvements could help with the latter, though?...)
True, I was mainly thinking about speeding up recompiling when editing DOM .rs and .webidl files. You can tell which case hurts me!
I don't think this is useful to keep this issue open. We know that splitting the script crate is something we can consider, but this will be done so far in the future (if ever) that I am hoping by then incremental compilation will make the crate size a non-issue.
@nox I want to point out, again, that incremental compilation will *not* make the memory footprint during build a non-issue.
The problem is still a real one, even if we don't have a clear vision of how to solve it, so I'd like to keep this issue open. If incremental computation makes this a non-issue, we can close the issue then.
>  Building it takes almost 40 seconds

Hahaha, the good old times
Any news on this issue ? Just having crashes by >4G memory consumption.
No news.
hmm, I'll try with kicking out stuff I dont wanna have anyways (bluetooth, gamepad, vr, ...).
unfortunately, #[cfg(...)] doesn't seem to work in many places - I really miss a real preprocessor.
Is the effort needed small, medium or xlarge?
The effort is still very large. I have proposed a [Google Summer of Code project](https://github.com/servo/servo/wiki/Prototype-ways-of-splitting-the-script-crate) to investigate the ideas we have discussed in this thread.
While trying to understand the idea, work that was already done, its problems and how associate types would be used for this I make this example:

```rust
mod script_bindings {
    // this module can be considered as forward declaratins
    // but in servo it should also contain all generated stuff from codegen (uses)
    // while actual defieinitions/implementations is outside

    pub trait TypeHolderTrait: Sized {
        type Dom: DomTrait<Self>;
        type WGPU: WgpuTrait<Self>;
    }

    // all exposed functions need to be behind trait
    // this is not a problem for webidl exposed methods
    // as the trait for them is generated by codegen
    pub trait DomTrait<TH: TypeHolderTrait> {
        fn method_on_dom(&self) -> &TH::WGPU;
    }

    pub trait WgpuTrait<TH: TypeHolderTrait> {
        fn method_on_wgpu(&self) -> &TH::Dom;
    }
}

mod script {
    use crate::script_bindings::TypeHolderTrait;
    use crate::script_bindings::DomTrait;

    pub struct ActualDom<TH: TypeHolderTrait> {
        wgpu: TH::WGPU,
    }

    /// This method is not exposed via traits,
    /// so users needs to depend on script directly
    ///
    /// See `uses_no_trait` for usage
    impl<TH: TypeHolderTrait> ActualDom<TH> {
        pub fn no_trait(&self) {

        }
    }

    impl<TH: TypeHolderTrait> DomTrait<TH> for ActualDom<TH> {
        fn method_on_dom(&self) -> &TH::WGPU {
            &self.wgpu
        }
    }

    pub fn start<TH: TypeHolderTrait>() {
        // ...
    }
}

mod script_webgpu {
    use crate::script_bindings::TypeHolderTrait;
    use crate::script_bindings::WgpuTrait;

    pub struct ActualWGPU<TH: TypeHolderTrait> {
        dom: TH::Dom,
    }

    /// Here we use associated type binding syntax to tell compiler
    /// to use script::ActualDom for Dom type
    /// this allows us to call methods on ActualDom that were not "forward declered" via traits
    impl<TH: TypeHolderTrait<Dom = crate::script::ActualDom<TH>>> ActualWGPU<TH> {
        pub fn uses_no_trait(&self) {
            self.dom.no_trait()
        }
    }

    impl<TH: TypeHolderTrait> WgpuTrait<TH> for ActualWGPU<TH> {
        fn method_on_wgpu(&self) -> &TH::Dom {
            &self.dom
        }
    }
}

/// This links implementations from script-* with "forward declarations" from script_bindings
pub struct TypeHolder;
impl script_bindings::TypeHolderTrait for TypeHolder {
    type Dom = script::ActualDom<Self>;
    type WGPU = script_webgpu::ActualWGPU<Self>;
}

fn main() {
    // when starting script we just need to put puzzle together
    script::start::<TypeHolder>();
}
```

and I must say I am thrilled. I think it should be feasible to separate codegen bindings/actual implementations and later we could even split actual implementations (see `script_webgpu`)
I'm going to try hacking together a really minimal script_bindings that uses real codegen on one interface, just to try to tease out what changes are necessary.
Well we already have https://github.com/servo/servo/pull/21371, I was thinking to go big and separate all generated code with implementations (`TypeHolderTrait` would generated by codegen). The main question I have is how to land such change (due to size).
https://github.com/servo/servo/compare/main...jdm:servo:script-split is the branch I worked on while flying on planes today. It successfully compiles with `RUSTC_BOOTSTRAP=1`; why does https://github.com/servo/servo/blob/main/components/script/lib.rs#L5 work for the script crate but fails to compile in the new script_bindings crate?

This feels promising! The codegen in script_bindings is spitting out this monster trait for my test webidl collection:
```rust
pub trait DomTypes: crate::utils::DomHelpers<Self> + Sized {
    type CSSStyleDeclaration: crate::dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::CSSStyleDeclaration>;
    type DOMException: crate::dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::DOMException>;
    type DOMParser: crate::dom::bindings::codegen::Bindings::DOMParserBinding::DOMParserMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::DOMParser>;
    type Document: crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::Document>;
    type GlobalScope: crate::dom::bindings::codegen::Bindings::GlobalScopeBinding::GlobalScopeMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::GlobalScope>;
    type Window: crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods<Self> + crate::reflector::DomObject + crate::reflector::DomGlobal<Self> + crate::conversions::IDLInterface + PartialEq + crate::reflector::DomObjectWrap<Self> + crate::inheritance::Castable + malloc_size_of::MallocSizeOf + crate::reflector::MutDomObject + crate::conversions::DerivedFrom<Self::GlobalScope> + crate::conversions::DerivedFrom<Self::Window>;
}
```
Then individual traits get parameterized like:
```rust
pub trait DOMParserMethods<D: DomTypes> {
    fn ParseFromString(&self, str: DOMString, type_: SupportedType) -> Fallible<DomRoot<D::Document>>;
    fn Constructor(global: &D::Window, proto: Option<HandleObject>) -> Result<DomRoot<D::DOMParser>, Error>;
}
```
And any bindings code that needs to interact with non-IDL methods for concrete DOM types needs to have the implementation provided by the script crate:
```rust
pub trait DomHelpers<D: crate::codegen::DomTypes::DomTypes> {
    fn throw_dom_exception(
        cx: crate::script_runtime::JSContext,
        global: &D::GlobalScope,
        result: crate::error::Error,
    );

    fn global_scope_from_object(obj: *mut JSObject) -> crate::root::DomRoot<D::GlobalScope>;

    fn global_scope_origin(global: &D::GlobalScope) -> &servo_url::MutableOrigin;
}
```
> It successfully compiles with RUSTC_BOOTSTRAP=1; why does https://github.com/servo/servo/blob/main/components/script/lib.rs#L5 work for the script crate but fails to compile in the new script_bindings crate?

Because we set `RUSTC_BOOTSTRAP` for specific crates here:
https://github.com/servo/servo/blob/2db9032e72bda6108b4eb5988eaf164141a61d64/.cargo/config.toml#L31-L33
> And any bindings code that needs to interact with non-IDL methods for concrete DOM types needs to have the implementation provided by the script crate

or use associated type binding syntax as shown above (will be needed for every consumer, so this is not appropriate for very used methods).
> > And any bindings code that needs to interact with non-IDL methods for concrete DOM types needs to have the implementation provided by the script crate
> 
> or use associated type binding syntax as shown above (will be needed for every consumer, so this is not appropriate for very used methods).

For non-IDL methods that are impl on concrete DOM types we can use specific traits for for concrete DOM types (ex: `GlobalScopeHelpers` that would be implemented on `GlobalScope`), to add this to traits that are impl on `DomTypes::GlobalScope`, we can use new Bindings.conf field:
```conf
'GlobalScope': {
    'traits': ['GlobalScopeHelpers'],
},
```
and user will have to manually define it in core script crate:
```rust
pub trait GlobalScopeHelpers<D: crate::codegen::DomTypes::DomTypes<GlobalScope = Self>> {
    fn global_scope_from_object(obj: *mut JSObject) -> DomRoot<Self>;

    fn global_scope_origin(global: &Self) -> &servo_url::MutableOrigin;
}
```

functions that are not methods should simply be defined in core script with generic arg `throw_dom_exception<D: DomTypes>(...)`.
I have created a document with all stuff in one place (and some more ideas) on how to do this: https://gist.github.com/sagudev/c4a029cfccda9553adac32749a9ba583
I am working on getting the script_bindings crate in my branch compiling with all real webidl files present. It's going surprisingly well so far.
> I am working on getting the script_bindings crate in my branch compiling with all real webidl files present. It's going surprisingly well so far.

I was actually planing to do this, after I make sure that we can also measure runtime performance, hence my work on speedometer.
My script_bindings crate is now compiling with all DOM interfaces present \o/ Next step is getting the script crate to use tho generated bindings. https://github.com/jdm/servo/tree/script-split has all the latest changes.
I've made good progress in that branch, and I've found ways to make the changes in script/ minimally invasive, but I'm now running into errors that make no sense and feel like some kind of compiler bug. There are thousands of errors where the compiler can't resolve normal impl method calls, and it's hard to figure out how to narrow down what's going on.
Like, seriously. What is going on here?
```
error[E0599]: no method named `chars` found for reference `&str` in the current scope
   --> components/script/textinput.rs:247:19
    |
247 |     for c in text.chars() {
    |                   ^^^^^
    |
    = help: items from traits can only be used if the trait is in scope
help: trait `TextSource` which provides `chars` is implemented but not in scope; perhaps you want to import it
    |
7   + use unicode_bidi::TextSource;
    |
help: there is a method `par_chars` with a similar name
    |
247 |     for c in text.par_chars() {
    |                   ~~~~~~~~~
```
let me try
I got:
```
servo/target/debug/build/script-607bfb53410c9870/out/InterfaceTypes.rs: No such file or directory (os error 2)
   --> components/script/dom/mod.rs:209:5
    |
209 |     include!(concat!(env!("OUT_DIR"), "/InterfaceTypes.rs"));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in the macro `include` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `script` (lib) due to 1 previous error
```
on https://github.com/jdm/servo/commit/b05a845b3881f287907be101d9363b7d3500f37f. So you might need to run `mach clean` to make sure rust is not using old generated files.
Same errors after addressing that.
Usually it's good idea to start looking at first errors and fixing them first (as those can cause more false errors later).

For me these are error due to orphaning rules:
```
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/bluetoothuuid.rs:627:1
    |
627 | impl Clone for StringOrUnsignedLong {
    | ^^^^^^^^^^^^^^^--------------------
    | |              |
    | |              `script_bindings::codegen::UnionTypes::StringOrUnsignedLong` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> components/script/dom/gpucanvascontext.rs:42:1
   |
42 | impl Clone for GPUCanvasConfiguration {
   | ^^^^^^^^^^^^^^^----------------------
   | |              |
   | |              `script_bindings::codegen::Bindings::WebGPUBinding::GPUCanvasConfiguration` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> components/script/dom/gpucanvascontext.rs:54:1
   |
54 | impl Clone for HTMLCanvasElementOrOffscreenCanvas {
   | ^^^^^^^^^^^^^^^----------------------------------
   | |              |
   | |              `script_bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/request.rs:876:1
    |
876 | impl Clone for HeadersInit {
    | ^^^^^^^^^^^^^^^-----------
    | |              |
    | |              `script_bindings::codegen::UnionTypes::ByteStringSequenceSequenceOrByteStringByteStringRecord` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> components/script/dom/gpucanvascontext.rs:63:1
   |
63 | impl malloc_size_of::MallocSizeOf for GPUTextureDescriptor {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------
   | |                                     |
   | |                                     `script_bindings::codegen::Bindings::WebGPUBinding::GPUTextureDescriptor` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> components/script/dom/gpucanvascontext.rs:86:1
   |
86 | impl malloc_size_of::MallocSizeOf for HTMLCanvasElementOrOffscreenCanvas {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------
   | |                                     |
   | |                                     `script_bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas` is not defined in the current crate
   | impl doesn't use only types from inside the current crate
   |
   = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/security_manager.rs:170:1
    |
170 | impl Serialize for SecurityPolicyViolationEventDisposition {
    | ^^^^^^^^^^^^^^^^^^^---------------------------------------
    | |                  |
    | |                  `SecurityPolicyViolationEventDisposition` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/audiobuffersourcenode.rs:264:1
    |
264 | impl<'a> From<&'a AudioBufferSourceOptions> for AudioBufferSourceNodeOptions {
    | ^^^^^^^^^----------------------------------^^^^^----------------------------
    | |        |                                      |
    | |        |                                      `AudioBufferSourceNodeOptions` is not defined in the current crate
    | |        `script_bindings::codegen::Bindings::AudioBufferSourceNodeBinding::AudioBufferSourceOptions` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/audionode.rs:370:1
    |
370 | impl From<ChannelCountMode> for ServoMediaChannelCountMode {
    | ^^^^^----------------------^^^^^--------------------------
    | |    |                          |
    | |    |                          `servo_media::servo_media_audio::node::ChannelCountMode` is not defined in the current crate
    | |    `script_bindings::codegen::Bindings::AudioNodeBinding::ChannelCountMode` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/audionode.rs:380:1
    |
380 | impl From<ChannelInterpretation> for ServoMediaChannelInterpretation {
    | ^^^^^---------------------------^^^^^-------------------------------
    | |    |                               |
    | |    |                               `servo_media::servo_media_audio::node::ChannelInterpretation` is not defined in the current crate
    | |    `script_bindings::codegen::Bindings::AudioNodeBinding::ChannelInterpretation` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/audioparam.rs:325:1
    |
325 | impl From<AutomationRate> for ParamRate {
    | ^^^^^--------------------^^^^^---------
    | |    |                        |
    | |    |                        `ParamRate` is not defined in the current crate
    | |    `AutomationRate` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
   --> components/script/dom/baseaudiocontext.rs:591:1
    |
591 | impl From<ProcessingState> for AudioContextState {
    | ^^^^^---------------------^^^^^-----------------
    | |    |                         |
    | |    |                         `AudioContextState` is not defined in the current crate
    | |    `ProcessingState` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
```

is 
```
error[E0599]: no method named `chars` found for reference `&str` in the current scope
``` 
your first error?
No, I've been skipping over those orphan rule violations because I understand them. I have not found going top to bottom to be the most useful strategy so far.
> I have not found going top to bottom to be the most useful strategy so far.

Well, it the most sure ways to fix proper error properly. I got burnt few times from fixing wrong errors at wrong time.
My branch now a) compiles, b) opens pages that don't use any JS. I know what's missing that should get JS working as well.

Fix patch:
diff --git a/components/script/dom/abstractrange.rs b/components/script/dom/abstractrange.rs
index f4f86566f4103..bced93d478b83 100644
--- a/components/script/dom/abstractrange.rs
+++ b/components/script/dom/abstractrange.rs
@@ -64,7 +64,7 @@ impl AbstractRange {
     }
 }
 
-impl AbstractRangeMethods for AbstractRange {
+impl AbstractRangeMethods<crate::DomTypeHolder> for AbstractRange {
     /// <https://dom.spec.whatwg.org/#dom-range-startcontainer>
     fn StartContainer(&self) -> DomRoot<Node> {
         self.start.node.get()
diff --git a/components/script/dom/analysernode.rs b/components/script/dom/analysernode.rs
index 486747ec8fbc7..47d8f255088e6 100644
--- a/components/script/dom/analysernode.rs
+++ b/components/script/dom/analysernode.rs
@@ -137,7 +137,7 @@ impl AnalyserNode {
     }
 }
 
-impl AnalyserNodeMethods for AnalyserNode {
+impl AnalyserNodeMethods<crate::DomTypeHolder> for AnalyserNode {
     /// <https://webaudio.github.io/web-audio-api/#dom-analysernode-analysernode>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/animationevent.rs b/components/script/dom/animationevent.rs
index c3a8655c49692..673db954bb025 100644
--- a/components/script/dom/animationevent.rs
+++ b/components/script/dom/animationevent.rs
@@ -68,7 +68,7 @@ impl AnimationEvent {
     }
 }
 
-impl AnimationEventMethods for AnimationEvent {
+impl AnimationEventMethods<crate::DomTypeHolder> for AnimationEvent {
     // https://drafts.csswg.org/css-animations/#dom-animationevent-animationevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs
index 140329ec4cc61..701175b0facdb 100644
--- a/components/script/dom/attr.rs
+++ b/components/script/dom/attr.rs
@@ -97,7 +97,7 @@ impl Attr {
     }
 }
 
-impl AttrMethods for Attr {
+impl AttrMethods<crate::DomTypeHolder> for Attr {
     // https://dom.spec.whatwg.org/#dom-attr-localname
     fn LocalName(&self) -> DOMString {
         // FIXME(ajeffrey): convert directly from LocalName to DOMString
diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs
index c28160c63a9d8..8b88cd0bcac4a 100644
--- a/components/script/dom/audiobuffer.rs
+++ b/components/script/dom/audiobuffer.rs
@@ -183,7 +183,7 @@ impl AudioBuffer {
     }
 }
 
-impl AudioBufferMethods for AudioBuffer {
+impl AudioBufferMethods<crate::DomTypeHolder> for AudioBuffer {
     // https://webaudio.github.io/web-audio-api/#dom-audiobuffer-audiobuffer
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/audiobuffersourcenode.rs b/components/script/dom/audiobuffersourcenode.rs
index a261aea9d1f08..3f559457b7ca5 100644
--- a/components/script/dom/audiobuffersourcenode.rs
+++ b/components/script/dom/audiobuffersourcenode.rs
@@ -123,7 +123,7 @@ impl AudioBufferSourceNode {
     }
 }
 
-impl AudioBufferSourceNodeMethods for AudioBufferSourceNode {
+impl AudioBufferSourceNodeMethods<crate::DomTypeHolder> for AudioBufferSourceNode {
     // https://webaudio.github.io/web-audio-api/#dom-audiobuffersourcenode-audiobuffersourcenode
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/audiocontext.rs b/components/script/dom/audiocontext.rs
index c67d25ff014c3..bf83796674e6e 100644
--- a/components/script/dom/audiocontext.rs
+++ b/components/script/dom/audiocontext.rs
@@ -109,7 +109,7 @@ impl AudioContext {
     }
 }
 
-impl AudioContextMethods for AudioContext {
+impl AudioContextMethods<crate::DomTypeHolder> for AudioContext {
     // https://webaudio.github.io/web-audio-api/#AudioContext-constructors
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/audiodestinationnode.rs b/components/script/dom/audiodestinationnode.rs
index a63daaf4587d1..f0071a2f111a8 100644
--- a/components/script/dom/audiodestinationnode.rs
+++ b/components/script/dom/audiodestinationnode.rs
@@ -48,7 +48,7 @@ impl AudioDestinationNode {
     }
 }
 
-impl AudioDestinationNodeMethods for AudioDestinationNode {
+impl AudioDestinationNodeMethods<crate::DomTypeHolder> for AudioDestinationNode {
     // https://webaudio.github.io/web-audio-api/#dom-audiodestinationnode-maxchannelcount
     fn MaxChannelCount(&self) -> u32 {
         MAX_CHANNEL_COUNT
diff --git a/components/script/dom/audiolistener.rs b/components/script/dom/audiolistener.rs
index ad8bdb071bac1..7f005ba77f161 100644
--- a/components/script/dom/audiolistener.rs
+++ b/components/script/dom/audiolistener.rs
@@ -160,7 +160,7 @@ impl AudioListener {
 }
 
 #[allow(non_snake_case)]
-impl AudioListenerMethods for AudioListener {
+impl AudioListenerMethods<crate::DomTypeHolder> for AudioListener {
     // https://webaudio.github.io/web-audio-api/#dom-audiolistener-positionx
     fn PositionX(&self) -> DomRoot<AudioParam> {
         DomRoot::from_ref(&self.position_x)
diff --git a/components/script/dom/audionode.rs b/components/script/dom/audionode.rs
index 728f2f401bb77..91431ca29284b 100644
--- a/components/script/dom/audionode.rs
+++ b/components/script/dom/audionode.rs
@@ -106,7 +106,7 @@ impl AudioNode {
     }
 }
 
-impl AudioNodeMethods for AudioNode {
+impl AudioNodeMethods<crate::DomTypeHolder> for AudioNode {
     // https://webaudio.github.io/web-audio-api/#dom-audionode-connect
     fn Connect(
         &self,
diff --git a/components/script/dom/audioparam.rs b/components/script/dom/audioparam.rs
index f54a478507384..5ba3ef1e95133 100644
--- a/components/script/dom/audioparam.rs
+++ b/components/script/dom/audioparam.rs
@@ -110,7 +110,7 @@ impl AudioParam {
     }
 }
 
-impl AudioParamMethods for AudioParam {
+impl AudioParamMethods<crate::DomTypeHolder> for AudioParam {
     // https://webaudio.github.io/web-audio-api/#dom-audioparam-automationrate
     fn AutomationRate(&self) -> AutomationRate {
         self.automation_rate.get()
diff --git a/components/script/dom/audioscheduledsourcenode.rs b/components/script/dom/audioscheduledsourcenode.rs
index e5f50c6b841eb..c8a970f390ee6 100644
--- a/components/script/dom/audioscheduledsourcenode.rs
+++ b/components/script/dom/audioscheduledsourcenode.rs
@@ -57,7 +57,7 @@ impl AudioScheduledSourceNode {
     }
 }
 
-impl AudioScheduledSourceNodeMethods for AudioScheduledSourceNode {
+impl AudioScheduledSourceNodeMethods<crate::DomTypeHolder> for AudioScheduledSourceNode {
     // https://webaudio.github.io/web-audio-api/#dom-audioscheduledsourcenode-onended
     event_handler!(ended, GetOnended, SetOnended);
 
diff --git a/components/script/dom/audiotrack.rs b/components/script/dom/audiotrack.rs
index 516e8c6ae9340..34666ae7d4402 100644
--- a/components/script/dom/audiotrack.rs
+++ b/components/script/dom/audiotrack.rs
@@ -85,7 +85,7 @@ impl AudioTrack {
     }
 }
 
-impl AudioTrackMethods for AudioTrack {
+impl AudioTrackMethods<crate::DomTypeHolder> for AudioTrack {
     // https://html.spec.whatwg.org/multipage/#dom-audiotrack-id
     fn Id(&self) -> DOMString {
         self.id()
diff --git a/components/script/dom/audiotracklist.rs b/components/script/dom/audiotracklist.rs
index b9f62c4b72e5f..a285c508eb4e3 100644
--- a/components/script/dom/audiotracklist.rs
+++ b/components/script/dom/audiotracklist.rs
@@ -117,7 +117,7 @@ impl AudioTrackList {
     }
 }
 
-impl AudioTrackListMethods for AudioTrackList {
+impl AudioTrackListMethods<crate::DomTypeHolder> for AudioTrackList {
     // https://html.spec.whatwg.org/multipage/#dom-audiotracklist-length
     fn Length(&self) -> u32 {
         self.len() as u32
diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs
index 1907878b4c98f..73ee5f39eb7ac 100644
--- a/components/script/dom/baseaudiocontext.rs
+++ b/components/script/dom/baseaudiocontext.rs
@@ -276,7 +276,7 @@ impl BaseAudioContext {
     }
 }
 
-impl BaseAudioContextMethods for BaseAudioContext {
+impl BaseAudioContextMethods<crate::DomTypeHolder> for BaseAudioContext {
     /// <https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-samplerate>
     fn SampleRate(&self) -> Finite<f32> {
         Finite::wrap(self.sample_rate)
diff --git a/components/script/dom/beforeunloadevent.rs b/components/script/dom/beforeunloadevent.rs
index 6a30336afe838..5df2bbc6452c7 100644
--- a/components/script/dom/beforeunloadevent.rs
+++ b/components/script/dom/beforeunloadevent.rs
@@ -51,7 +51,7 @@ impl BeforeUnloadEvent {
     }
 }
 
-impl BeforeUnloadEventMethods for BeforeUnloadEvent {
+impl BeforeUnloadEventMethods<crate::DomTypeHolder> for BeforeUnloadEvent {
     // https://html.spec.whatwg.org/multipage/#dom-beforeunloadevent-returnvalue
     fn ReturnValue(&self) -> DOMString {
         self.return_value.borrow().clone()
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index f716f4a8be137..6ac9ae1d5d9b0 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -540,6 +540,12 @@ def union_native_type(t):
     return f'UnionTypes::{name}'
 
 
+# Unfortunately, .capitalize() on a string will lowercase things inside the
+# string, which we do not want.
+def firstCap(string):
+    return f"{string[0].upper()}{string[1:]}"
+
+
 class JSToNativeConversionInfo():
     """
     An object representing information about a JS-to-native conversion.
@@ -643,11 +649,6 @@ def handleOptional(template, declType, default):
         assert (defaultValue is None) == (default is None)
         return JSToNativeConversionInfo(template, default, declType)
 
-    # Unfortunately, .capitalize() on a string will lowercase things inside the
-    # string, which we do not want.
-    def firstCap(string):
-        return f"{string[0].upper()}{string[1:]}"
-
     # Helper functions for dealing with failures due to the JS value being the
     # wrong type of value.
     def onFailureNotAnObject(failureCode):
@@ -2621,6 +2622,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
     imports = [
         'crate::dom',
         'crate::dom::bindings::import::base::*',
+        'crate::dom::bindings::codegen::DomTypes::DomTypes',
         'crate::dom::bindings::conversions::windowproxy_from_handlevalue',
         'crate::dom::bindings::record::Record',
         'crate::dom::types::*',
@@ -2658,6 +2660,108 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
                      typedefs=[], imports=imports, config=config)
 
 
+def DomTypes(descriptors, descriptorProvider, dictionaries, callbacks, typedefs, config):
+    traits = [
+        "js::rust::Trace",
+        "malloc_size_of::MallocSizeOf",
+        "Sized",
+    ]
+    joinedTraits = ' + '.join(traits)
+    elements = [CGGeneric(f"pub trait DomTypes: {joinedTraits} where Self: 'static {{\n")]
+    for descriptor in descriptors:
+        iface_name = descriptor.interface.identifier.name
+        traits = []
+
+        chain = descriptor.prototypeChain
+        upcast = descriptor.hasDescendants()
+
+        if not upcast:
+            # No other interface will implement DeriveFrom<Foo> for this Foo, so avoid
+            # implementing it for itself.
+            chain = chain[:-1]
+
+        if chain:
+            traits += ["crate::dom::bindings::inheritance::Castable"]
+
+        for parent in chain:
+            traits += [f"crate::dom::bindings::conversions::DerivedFrom<Self::{parent}>"]
+
+        iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
+        if iterableDecl:
+            if iterableDecl.isMaplike():
+                keytype = getRetvalDeclarationForType(iterableDecl.keyType, None).define()
+                valuetype = getRetvalDeclarationForType(iterableDecl.valueType, None).define()
+                traits += [f"crate::dom::bindings::like::Maplike<Key={keytype}, Value={valuetype}>"]
+            if iterableDecl.isSetlike():
+                keytype = getRetvalDeclarationForType(iterableDecl.keyType, None).define()
+                traits += [f"crate::dom::bindings::like::Setlike<Key={keytype}>"]
+            if iterableDecl.hasKeyType():
+                traits += [
+                    "crate::dom::bindings::reflector::DomObjectIteratorWrap",
+                ]
+
+        if descriptor.weakReferenceable:
+            traits += ["crate::dom::bindings::weakref::WeakReferenceable"]
+
+        if not descriptor.interface.isNamespace():
+            traits += [
+                "js::conversions::ToJSValConvertible",
+                "crate::dom::bindings::reflector::MutDomObject",
+                "crate::dom::bindings::reflector::DomObject",
+            ]
+
+        if descriptor.register:
+            if (
+                (descriptor.concrete or descriptor.hasDescendants())
+                and not descriptor.interface.isNamespace()
+                and not descriptor.interface.isIteratorInterface()
+            ):
+                traits += [
+                    "crate::dom::bindings::conversions::IDLInterface",
+                    "PartialEq",
+                ]
+
+            if descriptor.concrete and not descriptor.isGlobal():
+                traits += ["crate::dom::bindings::reflector::DomObjectWrap"]
+
+        if not descriptor.interface.isCallback() and not descriptor.interface.isIteratorInterface():
+            nonConstMembers = [m for m in descriptor.interface.members if not m.isConst()]
+            ctor = descriptor.interface.ctor()
+            if (
+                    nonConstMembers
+                    or (ctor and not ctor.isHTMLConstructor())
+                    or descriptor.interface.legacyFactoryFunctions
+            ):
+                namespace = f"{toBindingPath(descriptor)}"
+                traits += [f"crate::dom::bindings::codegen::Bindings::{namespace}::{iface_name}Methods<Self>"]
+            isPromise = firstCap(iface_name) == "Promise"
+            elements += [
+                CGGeneric("    #[crown::unrooted_must_root_lint::must_root]\n"),
+                CGGeneric("    #[crown::unrooted_must_root_lint::allow_unrooted_in_rc]\n" if isPromise else ""),
+                CGGeneric(f"    type {firstCap(iface_name)}: {' + '.join(traits)};\n")
+            ]
+    elements += [CGGeneric("}\n")]
+    return CGList([CGGeneric("use crate::dom::bindings::str::DOMString;\n")] + elements)
+
+
+def DomTypeHolder(descriptors, descriptorProvider, dictionaries, callbacks, typedefs, config):
+    elements = [
+        CGGeneric(
+            "#[derive(JSTraceable, MallocSizeOf, PartialEq)]\n"
+            "pub struct DomTypeHolder;\n"
+            "impl crate::DomTypes for DomTypeHolder {\n"
+        ),
+    ]
+    for descriptor in descriptors:
+        if descriptor.interface.isCallback() or descriptor.interface.isIteratorInterface():
+            continue
+        iface_name = descriptor.interface.identifier.name
+        path = f"crate::dom::{iface_name.lower()}::{firstCap(iface_name)}"
+        elements.append(CGGeneric(f"    type {firstCap(iface_name)} = {path};\n"))
+    elements.append(CGGeneric("}\n"))
+    return CGList(elements)
+
+
 class Argument():
     """
     A class for outputting the type and name of an argument
@@ -3061,6 +3165,12 @@ def definition_body(self):
 """)
 
 
+def toBindingPath(descriptor):
+    module = toBindingModuleFileFromDescriptor(descriptor)
+    namespace = toBindingNamespace(descriptor.interface.identifier.name)
+    return f"{module}::{namespace}"
+
+
 class CGIDLInterface(CGThing):
     """
     Class for codegen of an implementation of the IDLInterface trait.
@@ -6495,7 +6605,7 @@ def ctorMethod(ctor, baseName=None):
 
         if methods:
             self.cgRoot = CGWrapper(CGIndenter(CGList(methods, "")),
-                                    pre=f"pub trait {descriptor.interface.identifier.name}Methods {{\n",
+                                    pre=f"pub trait {descriptor.interface.identifier.name}Methods<D: DomTypes> {{\n",
                                     post="}")
         else:
             self.cgRoot = CGGeneric("")
@@ -8150,6 +8260,36 @@ def UnionTypes(config):
         # Done.
         return curr
 
+    @staticmethod
+    def DomTypes(config):
+        curr = DomTypes(config.getDescriptors(),
+                        config.getDescriptorProvider(),
+                        config.getDictionaries(),
+                        config.getCallbacks(),
+                        config.typedefs,
+                        config)
+
+        # Add the auto-generated comment.
+        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
+
+        # Done.
+        return curr
+
+    @staticmethod
+    def DomTypeHolder(config):
+        curr = DomTypeHolder(config.getDescriptors(),
+                             config.getDescriptorProvider(),
+                             config.getDictionaries(),
+                             config.getCallbacks(),
+                             config.typedefs,
+                             config)
+
+        # Add the auto-generated comment.
+        curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT)
+
+        # Done.
+        return curr
+
     @staticmethod
     def SupportedDomApis(config):
         descriptors = config.getDescriptors(isExposedConditionally=False)
diff --git a/components/script/dom/bindings/codegen/run.py b/components/script/dom/bindings/codegen/run.py
index 4bf5966e3050e..52840b1b1d33b 100644
--- a/components/script/dom/bindings/codegen/run.py
+++ b/components/script/dom/bindings/codegen/run.py
@@ -48,6 +48,8 @@ def main():
         ("InheritTypes", "InheritTypes.rs"),
         ("Bindings", "Bindings/mod.rs"),
         ("UnionTypes", "UnionTypes.rs"),
+        ("DomTypes", "DomTypes.rs"),
+        ("DomTypeHolder", "DomTypeHolder.rs"),
     ]:
         generate(config, name, os.path.join(out_dir, filename))
     make_dir(doc_servo)
diff --git a/components/script/dom/bindings/import.rs b/components/script/dom/bindings/import.rs
index 1f6f0cec97240..c4c7a460ca934 100644
--- a/components/script/dom/bindings/import.rs
+++ b/components/script/dom/bindings/import.rs
@@ -25,6 +25,7 @@ pub mod base {
         ChannelCountMode, ChannelCountModeValues, ChannelInterpretation,
         ChannelInterpretationValues,
     };
+    pub use crate::dom::bindings::codegen::DomTypes::DomTypes;
     pub use crate::dom::bindings::codegen::UnionTypes;
     pub use crate::dom::bindings::conversions::{
         root_from_handlevalue, ConversionBehavior, ConversionResult, FromJSValConvertible,
diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs
index d291f8e353fbb..a6666b70d90c9 100644
--- a/components/script/dom/bindings/mod.rs
+++ b/components/script/dom/bindings/mod.rs
@@ -170,6 +170,12 @@ pub mod xmlname;
 /// Generated JS-Rust bindings.
 #[allow(missing_docs, non_snake_case)]
 pub mod codegen {
+    pub mod DomTypeHolder {
+        include!(concat!(env!("OUT_DIR"), "/DomTypeHolder.rs"));
+    }
+    pub mod DomTypes {
+        include!(concat!(env!("OUT_DIR"), "/DomTypes.rs"));
+    }
     #[allow(dead_code)]
     pub mod Bindings {
         include!(concat!(env!("OUT_DIR"), "/Bindings/mod.rs"));
diff --git a/components/script/dom/biquadfilternode.rs b/components/script/dom/biquadfilternode.rs
index 92d39503690c0..be0d8fdecea5a 100644
--- a/components/script/dom/biquadfilternode.rs
+++ b/components/script/dom/biquadfilternode.rs
@@ -140,7 +140,7 @@ impl BiquadFilterNode {
     }
 }
 
-impl BiquadFilterNodeMethods for BiquadFilterNode {
+impl BiquadFilterNodeMethods<crate::DomTypeHolder> for BiquadFilterNode {
     // https://webaudio.github.io/web-audio-api/#dom-biquadfilternode-biquadfilternode-context-options
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs
index 31c6fa6462081..e92d64d1958a3 100644
--- a/components/script/dom/blob.rs
+++ b/components/script/dom/blob.rs
@@ -202,7 +202,7 @@ pub fn blob_parts_to_bytes(
     Ok(ret)
 }
 
-impl BlobMethods for Blob {
+impl BlobMethods<crate::DomTypeHolder> for Blob {
     // https://w3c.github.io/FileAPI/#constructorBlob
     #[allow(non_snake_case)]
     fn Constructor(
diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs
index 2799bfae29cd9..4d9c58a44ff28 100644
--- a/components/script/dom/bluetooth.rs
+++ b/components/script/dom/bluetooth.rs
@@ -534,7 +534,7 @@ impl From<BluetoothError> for Error {
     }
 }
 
-impl BluetoothMethods for Bluetooth {
+impl BluetoothMethods<crate::DomTypeHolder> for Bluetooth {
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
     fn RequestDevice(
         &self,
diff --git a/components/script/dom/bluetoothadvertisingevent.rs b/components/script/dom/bluetoothadvertisingevent.rs
index 6d1909c17ef4f..0fc7a4dbe8bf5 100644
--- a/components/script/dom/bluetoothadvertisingevent.rs
+++ b/components/script/dom/bluetoothadvertisingevent.rs
@@ -81,7 +81,7 @@ impl BluetoothAdvertisingEvent {
     }
 }
 
-impl BluetoothAdvertisingEventMethods for BluetoothAdvertisingEvent {
+impl BluetoothAdvertisingEventMethods<crate::DomTypeHolder> for BluetoothAdvertisingEvent {
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-bluetoothadvertisingevent
     #[allow(non_snake_case)]
     fn Constructor(
diff --git a/components/script/dom/bluetoothcharacteristicproperties.rs b/components/script/dom/bluetoothcharacteristicproperties.rs
index be322eec17acf..addfd0c8719f7 100644
--- a/components/script/dom/bluetoothcharacteristicproperties.rs
+++ b/components/script/dom/bluetoothcharacteristicproperties.rs
@@ -82,7 +82,9 @@ impl BluetoothCharacteristicProperties {
     }
 }
 
-impl BluetoothCharacteristicPropertiesMethods for BluetoothCharacteristicProperties {
+impl BluetoothCharacteristicPropertiesMethods<crate::DomTypeHolder>
+    for BluetoothCharacteristicProperties
+{
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothcharacteristicproperties-broadcast
     fn Broadcast(&self) -> bool {
         self.broadcast
diff --git a/components/script/dom/bluetoothdevice.rs b/components/script/dom/bluetoothdevice.rs
index 8fd8e316f3b7f..97d438210e8cf 100644
--- a/components/script/dom/bluetoothdevice.rs
+++ b/components/script/dom/bluetoothdevice.rs
@@ -253,7 +253,7 @@ impl BluetoothDevice {
     }
 }
 
-impl BluetoothDeviceMethods for BluetoothDevice {
+impl BluetoothDeviceMethods<crate::DomTypeHolder> for BluetoothDevice {
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-id
     fn Id(&self) -> DOMString {
         self.id.clone()
diff --git a/components/script/dom/bluetoothpermissionresult.rs b/components/script/dom/bluetoothpermissionresult.rs
index 37dfe234da119..2b540d977b5bd 100644
--- a/components/script/dom/bluetoothpermissionresult.rs
+++ b/components/script/dom/bluetoothpermissionresult.rs
@@ -81,7 +81,7 @@ impl BluetoothPermissionResult {
     }
 }
 
-impl BluetoothPermissionResultMethods for BluetoothPermissionResult {
+impl BluetoothPermissionResultMethods<crate::DomTypeHolder> for BluetoothPermissionResult {
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothpermissionresult-devices
     fn Devices(&self) -> Vec<DomRoot<BluetoothDevice>> {
         let device_vec: Vec<DomRoot<BluetoothDevice>> = self
diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs
index ccf4623e6216c..207b4e438f3f9 100644
--- a/components/script/dom/bluetoothremotegattcharacteristic.rs
+++ b/components/script/dom/bluetoothremotegattcharacteristic.rs
@@ -91,7 +91,9 @@ impl BluetoothRemoteGATTCharacteristic {
     }
 }
 
-impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteristic {
+impl BluetoothRemoteGATTCharacteristicMethods<crate::DomTypeHolder>
+    for BluetoothRemoteGATTCharacteristic
+{
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-properties
     fn Properties(&self) -> DomRoot<BluetoothCharacteristicProperties> {
         DomRoot::from_ref(&self.properties)
diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs
index 0cbac631666c1..9492ecd73634d 100644
--- a/components/script/dom/bluetoothremotegattdescriptor.rs
+++ b/components/script/dom/bluetoothremotegattdescriptor.rs
@@ -78,7 +78,7 @@ impl BluetoothRemoteGATTDescriptor {
     }
 }
 
-impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
+impl BluetoothRemoteGATTDescriptorMethods<crate::DomTypeHolder> for BluetoothRemoteGATTDescriptor {
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-characteristic
     fn Characteristic(&self) -> DomRoot<BluetoothRemoteGATTCharacteristic> {
         DomRoot::from_ref(&self.characteristic)
diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs
index 07f0a2d575130..b386693d17221 100644
--- a/components/script/dom/bluetoothremotegattserver.rs
+++ b/components/script/dom/bluetoothremotegattserver.rs
@@ -58,7 +58,7 @@ impl BluetoothRemoteGATTServer {
     }
 }
 
-impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
+impl BluetoothRemoteGATTServerMethods<crate::DomTypeHolder> for BluetoothRemoteGATTServer {
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-device
     fn Device(&self) -> DomRoot<BluetoothDevice> {
         DomRoot::from_ref(&self.device)
diff --git a/components/script/dom/bluetoothremotegattservice.rs b/components/script/dom/bluetoothremotegattservice.rs
index 5d696555f68c2..7d951fea22291 100644
--- a/components/script/dom/bluetoothremotegattservice.rs
+++ b/components/script/dom/bluetoothremotegattservice.rs
@@ -68,7 +68,7 @@ impl BluetoothRemoteGATTService {
     }
 }
 
-impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
+impl BluetoothRemoteGATTServiceMethods<crate::DomTypeHolder> for BluetoothRemoteGATTService {
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-device
     fn Device(&self) -> DomRoot<BluetoothDevice> {
         DomRoot::from_ref(&self.device)
diff --git a/components/script/dom/bluetoothuuid.rs b/components/script/dom/bluetoothuuid.rs
index 529c817f3316b..9c2d053f8d7da 100644
--- a/components/script/dom/bluetoothuuid.rs
+++ b/components/script/dom/bluetoothuuid.rs
@@ -584,7 +584,7 @@ const CHARACTERISTIC_ERROR_MESSAGE: &str =
 const DESCRIPTOR_ERROR_MESSAGE: &str = "https://developer.bluetooth.org/gatt/descriptors/Pages/\
      DescriptorsHomePage.aspx\ne.g. 'gatt.characteristic_presentation_format'.";
 
-impl BluetoothUUIDMethods for BluetoothUUID {
+impl BluetoothUUIDMethods<crate::DomTypeHolder> for BluetoothUUID {
     // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-canonicaluuid
     fn CanonicalUUID(_: &Window, alias: u32) -> UUID {
         canonical_uuid(alias)
diff --git a/components/script/dom/broadcastchannel.rs b/components/script/dom/broadcastchannel.rs
index 7302aded9c7a1..dd0699ff8951a 100644
--- a/components/script/dom/broadcastchannel.rs
+++ b/components/script/dom/broadcastchannel.rs
@@ -66,7 +66,7 @@ impl BroadcastChannel {
     }
 }
 
-impl BroadcastChannelMethods for BroadcastChannel {
+impl BroadcastChannelMethods<crate::DomTypeHolder> for BroadcastChannel {
     /// <https://html.spec.whatwg.org/multipage/#broadcastchannel>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs
index f1317dd0a9075..93328b545eefc 100644
--- a/components/script/dom/canvasgradient.rs
+++ b/components/script/dom/canvasgradient.rs
@@ -47,7 +47,7 @@ impl CanvasGradient {
     }
 }
 
-impl CanvasGradientMethods for CanvasGradient {
+impl CanvasGradientMethods<crate::DomTypeHolder> for CanvasGradient {
     // https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop
     fn AddColorStop(&self, offset: Finite<f64>, color: DOMString, can_gc: CanGc) -> ErrorResult {
         if *offset < 0f64 || *offset > 1f64 {
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index bc131b94eab0f..592359d486a7e 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -154,7 +154,7 @@ impl LayoutCanvasRenderingContext2DHelpers for LayoutDom<'_, CanvasRenderingCont
 //  Restricted values are guarded in glue code. Therefore we need not add a guard.
 //
 // FIXME: this behavior should might be generated by some annotattions to idl.
-impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
+impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingContext2D {
     // https://html.spec.whatwg.org/multipage/#dom-context-2d-canvas
     fn Canvas(&self) -> DomRoot<HTMLCanvasElement> {
         // This method is not called from a paint worklet rendering context,
diff --git a/components/script/dom/channelmergernode.rs b/components/script/dom/channelmergernode.rs
index 47d1e1600f356..db9cb5c7e5543 100644
--- a/components/script/dom/channelmergernode.rs
+++ b/components/script/dom/channelmergernode.rs
@@ -84,7 +84,7 @@ impl ChannelMergerNode {
     }
 }
 
-impl ChannelMergerNodeMethods for ChannelMergerNode {
+impl ChannelMergerNodeMethods<crate::DomTypeHolder> for ChannelMergerNode {
     /// <https://webaudio.github.io/web-audio-api/#dom-channelmergernode-channelmergernode>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/channelsplitternode.rs b/components/script/dom/channelsplitternode.rs
index 29d7a92f94f69..a058a898c8509 100644
--- a/components/script/dom/channelsplitternode.rs
+++ b/components/script/dom/channelsplitternode.rs
@@ -86,7 +86,7 @@ impl ChannelSplitterNode {
     }
 }
 
-impl ChannelSplitterNodeMethods for ChannelSplitterNode {
+impl ChannelSplitterNodeMethods<crate::DomTypeHolder> for ChannelSplitterNode {
     /// <https://webaudio.github.io/web-audio-api/#dom-channelsplitternode-channelsplitternode>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs
index 4c53a09ca608d..cc523e13964ed 100644
--- a/components/script/dom/characterdata.rs
+++ b/components/script/dom/characterdata.rs
@@ -107,7 +107,7 @@ impl CharacterData {
     }
 }
 
-impl CharacterDataMethods for CharacterData {
+impl CharacterDataMethods<crate::DomTypeHolder> for CharacterData {
     // https://dom.spec.whatwg.org/#dom-characterdata-data
     fn Data(&self) -> DOMString {
         self.data.borrow().clone()
diff --git a/components/script/dom/client.rs b/components/script/dom/client.rs
index 610f4671bbd2b..5c87ec2acd26c 100644
--- a/components/script/dom/client.rs
+++ b/components/script/dom/client.rs
@@ -56,7 +56,7 @@ impl Client {
     }
 }
 
-impl ClientMethods for Client {
+impl ClientMethods<crate::DomTypeHolder> for Client {
     // https://w3c.github.io/ServiceWorker/#client-url-attribute
     fn Url(&self) -> USVString {
         USVString(self.url.as_str().to_owned())
diff --git a/components/script/dom/closeevent.rs b/components/script/dom/closeevent.rs
index 6fc7fdcb2c66d..3b7faf973561c 100644
--- a/components/script/dom/closeevent.rs
+++ b/components/script/dom/closeevent.rs
@@ -75,7 +75,7 @@ impl CloseEvent {
     }
 }
 
-impl CloseEventMethods for CloseEvent {
+impl CloseEventMethods<crate::DomTypeHolder> for CloseEvent {
     // https://websockets.spec.whatwg.org/#the-closeevent-interface
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/comment.rs b/components/script/dom/comment.rs
index 8a6b41c44f6bf..a5b9fd4c43a50 100644
--- a/components/script/dom/comment.rs
+++ b/components/script/dom/comment.rs
@@ -44,7 +44,7 @@ impl Comment {
     }
 }
 
-impl CommentMethods for Comment {
+impl CommentMethods<crate::DomTypeHolder> for Comment {
     /// <https://dom.spec.whatwg.org/#dom-comment-comment>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/compositionevent.rs b/components/script/dom/compositionevent.rs
index 6d602acead76b..d48c6f79b538c 100644
--- a/components/script/dom/compositionevent.rs
+++ b/components/script/dom/compositionevent.rs
@@ -82,7 +82,7 @@ impl CompositionEvent {
     }
 }
 
-impl CompositionEventMethods for CompositionEvent {
+impl CompositionEventMethods<crate::DomTypeHolder> for CompositionEvent {
     // https://w3c.github.io/uievents/#dom-compositionevent-compositionevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/console.rs b/components/script/dom/console.rs
index 2c9d01236e7c0..7effcababd6b1 100644
--- a/components/script/dom/console.rs
+++ b/components/script/dom/console.rs
@@ -227,7 +227,7 @@ fn console_message(global: &GlobalScope, message: DOMString, level: LogLevel) {
     })
 }
 
-impl consoleMethods for Console {
+impl consoleMethods<crate::DomTypeHolder> for Console {
     // https://developer.mozilla.org/en-US/docs/Web/API/Console/log
     fn Log(_cx: JSContext, global: &GlobalScope, messages: Vec<HandleValue>) {
         console_messages(global, messages, LogLevel::Log)
diff --git a/components/script/dom/constantsourcenode.rs b/components/script/dom/constantsourcenode.rs
index 20de035e0f5cf..76735093d39f7 100644
--- a/components/script/dom/constantsourcenode.rs
+++ b/components/script/dom/constantsourcenode.rs
@@ -90,7 +90,7 @@ impl ConstantSourceNode {
     }
 }
 
-impl ConstantSourceNodeMethods for ConstantSourceNode {
+impl ConstantSourceNodeMethods<crate::DomTypeHolder> for ConstantSourceNode {
     // https://webaudio.github.io/web-audio-api/#dom-constantsourcenode-constantsourcenode
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/crypto.rs b/components/script/dom/crypto.rs
index 4f71d6a29c07a..39ed78efae001 100644
--- a/components/script/dom/crypto.rs
+++ b/components/script/dom/crypto.rs
@@ -42,7 +42,7 @@ impl Crypto {
     }
 }
 
-impl CryptoMethods for Crypto {
+impl CryptoMethods<crate::DomTypeHolder> for Crypto {
     /// <https://w3c.github.io/webcrypto/#dfn-Crypto-attribute-subtle>
     fn Subtle(&self) -> DomRoot<SubtleCrypto> {
         self.subtle.or_init(|| SubtleCrypto::new(&self.global()))
diff --git a/components/script/dom/cryptokey.rs b/components/script/dom/cryptokey.rs
index 15918d6690812..47e52cb1b5d65 100644
--- a/components/script/dom/cryptokey.rs
+++ b/components/script/dom/cryptokey.rs
@@ -116,7 +116,7 @@ impl CryptoKey {
     }
 }
 
-impl CryptoKeyMethods for CryptoKey {
+impl CryptoKeyMethods<crate::DomTypeHolder> for CryptoKey {
     /// <https://w3c.github.io/webcrypto/#dom-cryptokey-type>
     fn Type(&self) -> KeyType {
         self.key_type
diff --git a/components/script/dom/css.rs b/components/script/dom/css.rs
index 99cc6c353e73e..6105ce806292f 100644
--- a/components/script/dom/css.rs
+++ b/components/script/dom/css.rs
@@ -25,7 +25,7 @@ pub struct CSS {
     reflector_: Reflector,
 }
 
-impl CSSMethods for CSS {
+impl CSSMethods<crate::DomTypeHolder> for CSS {
     /// <https://drafts.csswg.org/cssom/#the-css.escape()-method>
     fn Escape(_: &Window, ident: DOMString) -> Fallible<DOMString> {
         let mut escaped = String::new();
diff --git a/components/script/dom/cssconditionrule.rs b/components/script/dom/cssconditionrule.rs
index bdda803c012e5..78d7cfa25245d 100644
--- a/components/script/dom/cssconditionrule.rs
+++ b/components/script/dom/cssconditionrule.rs
@@ -39,7 +39,7 @@ impl CSSConditionRule {
     }
 }
 
-impl CSSConditionRuleMethods for CSSConditionRule {
+impl CSSConditionRuleMethods<crate::DomTypeHolder> for CSSConditionRule {
     /// <https://drafts.csswg.org/css-conditional-3/#dom-cssconditionrule-conditiontext>
     fn ConditionText(&self) -> DOMString {
         if let Some(rule) = self.downcast::<CSSMediaRule>() {
diff --git a/components/script/dom/cssgroupingrule.rs b/components/script/dom/cssgroupingrule.rs
index 60babba658c98..8dbfd4ac7ccee 100644
--- a/components/script/dom/cssgroupingrule.rs
+++ b/components/script/dom/cssgroupingrule.rs
@@ -58,7 +58,7 @@ impl CSSGroupingRule {
     }
 }
 
-impl CSSGroupingRuleMethods for CSSGroupingRule {
+impl CSSGroupingRuleMethods<crate::DomTypeHolder> for CSSGroupingRule {
     // https://drafts.csswg.org/cssom/#dom-cssgroupingrule-cssrules
     fn CssRules(&self) -> DomRoot<CSSRuleList> {
         // XXXManishearth check origin clean flag
diff --git a/components/script/dom/cssimportrule.rs b/components/script/dom/cssimportrule.rs
index d75ec29146058..1bebbeb90f707 100644
--- a/components/script/dom/cssimportrule.rs
+++ b/components/script/dom/cssimportrule.rs
@@ -63,7 +63,7 @@ impl SpecificCSSRule for CSSImportRule {
     }
 }
 
-impl CSSImportRuleMethods for CSSImportRule {
+impl CSSImportRuleMethods<crate::DomTypeHolder> for CSSImportRule {
     /// <https://drafts.csswg.org/cssom-1/#dom-cssimportrule-layername>
     fn GetLayerName(&self) -> Option<DOMString> {
         let guard = self.cssrule.shared_lock().read();
diff --git a/components/script/dom/csskeyframerule.rs b/components/script/dom/csskeyframerule.rs
index f53f68956fbe9..c30b6b28fbb4c 100644
--- a/components/script/dom/csskeyframerule.rs
+++ b/components/script/dom/csskeyframerule.rs
@@ -55,7 +55,7 @@ impl CSSKeyframeRule {
     }
 }
 
-impl CSSKeyframeRuleMethods for CSSKeyframeRule {
+impl CSSKeyframeRuleMethods<crate::DomTypeHolder> for CSSKeyframeRule {
     // https://drafts.csswg.org/css-animations/#dom-csskeyframerule-style
     fn Style(&self) -> DomRoot<CSSStyleDeclaration> {
         self.style_decl.or_init(|| {
diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs
index 272e7086a41d1..4457bd0b1174f 100644
--- a/components/script/dom/csskeyframesrule.rs
+++ b/components/script/dom/csskeyframesrule.rs
@@ -88,7 +88,7 @@ impl CSSKeyframesRule {
     }
 }
 
-impl CSSKeyframesRuleMethods for CSSKeyframesRule {
+impl CSSKeyframesRuleMethods<crate::DomTypeHolder> for CSSKeyframesRule {
     // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-cssrules
     fn CssRules(&self) -> DomRoot<CSSRuleList> {
         self.rulelist()
diff --git a/components/script/dom/csslayerblockrule.rs b/components/script/dom/csslayerblockrule.rs
index 21db85c2f6dd2..dba11279a658e 100644
--- a/components/script/dom/csslayerblockrule.rs
+++ b/components/script/dom/csslayerblockrule.rs
@@ -66,7 +66,7 @@ impl SpecificCSSRule for CSSLayerBlockRule {
     }
 }
 
-impl CSSLayerBlockRuleMethods for CSSLayerBlockRule {
+impl CSSLayerBlockRuleMethods<crate::DomTypeHolder> for CSSLayerBlockRule {
     /// <https://drafts.csswg.org/css-cascade-5/#dom-csslayerblockrule-name>
     fn Name(&self) -> DOMString {
         if let Some(name) = &self.layerblockrule.name {
diff --git a/components/script/dom/csslayerstatementrule.rs b/components/script/dom/csslayerstatementrule.rs
index dd9e632701d25..8f012c0e41ad3 100644
--- a/components/script/dom/csslayerstatementrule.rs
+++ b/components/script/dom/csslayerstatementrule.rs
@@ -65,7 +65,7 @@ impl SpecificCSSRule for CSSLayerStatementRule {
     }
 }
 
-impl CSSLayerStatementRuleMethods for CSSLayerStatementRule {
+impl CSSLayerStatementRuleMethods<crate::DomTypeHolder> for CSSLayerStatementRule {
     /// <https://drafts.csswg.org/css-cascade-5/#dom-csslayerstatementrule-namelist>
     fn NameList(&self, cx: SafeJSContext, retval: MutableHandleValue) {
         let names: Vec<DOMString> = self
diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs
index 3ecf63b1c226b..53abf8ffa0aec 100644
--- a/components/script/dom/cssmediarule.rs
+++ b/components/script/dom/cssmediarule.rs
@@ -78,7 +78,7 @@ impl SpecificCSSRule for CSSMediaRule {
     }
 }
 
-impl CSSMediaRuleMethods for CSSMediaRule {
+impl CSSMediaRuleMethods<crate::DomTypeHolder> for CSSMediaRule {
     // https://drafts.csswg.org/cssom/#dom-cssgroupingrule-media
     fn Media(&self) -> DomRoot<MediaList> {
         self.medialist()
diff --git a/components/script/dom/cssnamespacerule.rs b/components/script/dom/cssnamespacerule.rs
index 30395f0158b26..ea2a10bb26012 100644
--- a/components/script/dom/cssnamespacerule.rs
+++ b/components/script/dom/cssnamespacerule.rs
@@ -50,7 +50,7 @@ impl CSSNamespaceRule {
     }
 }
 
-impl CSSNamespaceRuleMethods for CSSNamespaceRule {
+impl CSSNamespaceRuleMethods<crate::DomTypeHolder> for CSSNamespaceRule {
     // https://drafts.csswg.org/cssom/#dom-cssnamespacerule-prefix
     fn Prefix(&self) -> DOMString {
         self.namespacerule
diff --git a/components/script/dom/cssrule.rs b/components/script/dom/cssrule.rs
index de648ca849bf8..6f688d5363ef5 100644
--- a/components/script/dom/cssrule.rs
+++ b/components/script/dom/cssrule.rs
@@ -148,7 +148,7 @@ impl CSSRule {
     }
 }
 
-impl CSSRuleMethods for CSSRule {
+impl CSSRuleMethods<crate::DomTypeHolder> for CSSRule {
     // https://drafts.csswg.org/cssom/#dom-cssrule-type
     fn Type(&self) -> u16 {
         let rule_type = self.as_specific().ty() as u16;
diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs
index 72c1da222921f..280374ba34d52 100644
--- a/components/script/dom/cssrulelist.rs
+++ b/components/script/dom/cssrulelist.rs
@@ -207,7 +207,7 @@ impl CSSRuleList {
     }
 }
 
-impl CSSRuleListMethods for CSSRuleList {
+impl CSSRuleListMethods<crate::DomTypeHolder> for CSSRuleList {
     // https://drafts.csswg.org/cssom/#ref-for-dom-cssrulelist-item-1
     fn Item(&self, idx: u32) -> Option<DomRoot<CSSRule>> {
         self.item(idx)
diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs
index f981c131c3ef4..b2d6bb6637ebf 100644
--- a/components/script/dom/cssstyledeclaration.rs
+++ b/components/script/dom/cssstyledeclaration.rs
@@ -383,7 +383,7 @@ pub static ENABLED_LONGHAND_PROPERTIES: LazyLock<Vec<LonghandId>> = LazyLock::ne
     enabled_longhands
 });
 
-impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
+impl CSSStyleDeclarationMethods<crate::DomTypeHolder> for CSSStyleDeclaration {
     // https://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length
     fn Length(&self) -> u32 {
         if self.readonly {
diff --git a/components/script/dom/cssstylerule.rs b/components/script/dom/cssstylerule.rs
index f2e6c279d0eb4..8a06cb79abd29 100644
--- a/components/script/dom/cssstylerule.rs
+++ b/components/script/dom/cssstylerule.rs
@@ -71,7 +71,7 @@ impl SpecificCSSRule for CSSStyleRule {
     }
 }
 
-impl CSSStyleRuleMethods for CSSStyleRule {
+impl CSSStyleRuleMethods<crate::DomTypeHolder> for CSSStyleRule {
     // https://drafts.csswg.org/cssom/#dom-cssstylerule-style
     fn Style(&self) -> DomRoot<CSSStyleDeclaration> {
         self.style_decl.or_init(|| {
diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs
index a83c90e0f783b..f25ffa14b8ea7 100644
--- a/components/script/dom/cssstylesheet.rs
+++ b/components/script/dom/cssstylesheet.rs
@@ -114,7 +114,7 @@ impl CSSStyleSheet {
     }
 }
 
-impl CSSStyleSheetMethods for CSSStyleSheet {
+impl CSSStyleSheetMethods<crate::DomTypeHolder> for CSSStyleSheet {
     // https://drafts.csswg.org/cssom/#dom-cssstylesheet-cssrules
     fn GetCssRules(&self) -> Fallible<DomRoot<CSSRuleList>> {
         if !self.origin_clean.get() {
diff --git a/components/script/dom/cssstylevalue.rs b/components/script/dom/cssstylevalue.rs
index e65e929e52039..83bab3a23a00b 100644
--- a/components/script/dom/cssstylevalue.rs
+++ b/components/script/dom/cssstylevalue.rs
@@ -31,7 +31,7 @@ impl CSSStyleValue {
     }
 }
 
-impl CSSStyleValueMethods for CSSStyleValue {
+impl CSSStyleValueMethods<crate::DomTypeHolder> for CSSStyleValue {
     /// <https://drafts.css-houdini.org/css-typed-om-1/#CSSStyleValue-stringification-behavior>
     fn Stringifier(&self) -> DOMString {
         DOMString::from(&*self.value)
diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs
index dd8675b066da3..aa2bd0cc597f6 100644
--- a/components/script/dom/customelementregistry.rs
+++ b/components/script/dom/customelementregistry.rs
@@ -332,7 +332,7 @@ fn get_callback(
     }
 }
 
-impl CustomElementRegistryMethods for CustomElementRegistry {
+impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistry {
     #[allow(unsafe_code, crown::unrooted_must_root)]
     /// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define>
     fn Define(
diff --git a/components/script/dom/customevent.rs b/components/script/dom/customevent.rs
index 459747b6ca416..4b82f3356439e 100644
--- a/components/script/dom/customevent.rs
+++ b/components/script/dom/customevent.rs
@@ -84,7 +84,7 @@ impl CustomEvent {
     }
 }
 
-impl CustomEventMethods for CustomEvent {
+impl CustomEventMethods<crate::DomTypeHolder> for CustomEvent {
     // https://dom.spec.whatwg.org/#dom-customevent-customevent
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index 5b106fd649b51..0611908fe007d 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -646,7 +646,7 @@ unsafe extern "C" fn interrupt_callback(cx: *mut JSContext) -> bool {
     !worker.is_closing()
 }
 
-impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope {
+impl DedicatedWorkerGlobalScopeMethods<crate::DomTypeHolder> for DedicatedWorkerGlobalScope {
     /// <https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage>
     fn PostMessage(
         &self,
diff --git a/components/script/dom/dissimilaroriginlocation.rs b/components/script/dom/dissimilaroriginlocation.rs
index da2221bf9f6fc..338145fe97869 100644
--- a/components/script/dom/dissimilaroriginlocation.rs
+++ b/components/script/dom/dissimilaroriginlocation.rs
@@ -44,7 +44,7 @@ impl DissimilarOriginLocation {
     }
 }
 
-impl DissimilarOriginLocationMethods for DissimilarOriginLocation {
+impl DissimilarOriginLocationMethods<crate::DomTypeHolder> for DissimilarOriginLocation {
     // https://html.spec.whatwg.org/multipage/#dom-location-href
     fn GetHref(&self) -> Fallible<USVString> {
         Err(Error::Security)
diff --git a/components/script/dom/dissimilaroriginwindow.rs b/components/script/dom/dissimilaroriginwindow.rs
index 6085de8fe8f8b..c673286e479e0 100644
--- a/components/script/dom/dissimilaroriginwindow.rs
+++ b/components/script/dom/dissimilaroriginwindow.rs
@@ -79,7 +79,7 @@ impl DissimilarOriginWindow {
     }
 }
 
-impl DissimilarOriginWindowMethods for DissimilarOriginWindow {
+impl DissimilarOriginWindowMethods<crate::DomTypeHolder> for DissimilarOriginWindow {
     // https://html.spec.whatwg.org/multipage/#dom-window
     fn Window(&self) -> DomRoot<WindowProxy> {
         self.window_proxy()
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 5baa48c4e3315..dc228788b94d0 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -4269,7 +4269,7 @@ impl ProfilerMetadataFactory for Document {
 }
 
 #[allow(non_snake_case)]
-impl DocumentMethods for Document {
+impl DocumentMethods<crate::DomTypeHolder> for Document {
     // https://dom.spec.whatwg.org/#dom-document-document
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/documentfragment.rs b/components/script/dom/documentfragment.rs
index 5c8165c06a766..bbf382c584f80 100644
--- a/components/script/dom/documentfragment.rs
+++ b/components/script/dom/documentfragment.rs
@@ -62,7 +62,7 @@ impl DocumentFragment {
     }
 }
 
-impl DocumentFragmentMethods for DocumentFragment {
+impl DocumentFragmentMethods<crate::DomTypeHolder> for DocumentFragment {
     // https://dom.spec.whatwg.org/#dom-documentfragment-documentfragment
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/documenttype.rs b/components/script/dom/documenttype.rs
index c038465057753..a9b6d696f9745 100644
--- a/components/script/dom/documenttype.rs
+++ b/components/script/dom/documenttype.rs
@@ -71,7 +71,7 @@ impl DocumentType {
     }
 }
 
-impl DocumentTypeMethods for DocumentType {
+impl DocumentTypeMethods<crate::DomTypeHolder> for DocumentType {
     // https://dom.spec.whatwg.org/#dom-documenttype-name
     fn Name(&self) -> DOMString {
         self.name.clone()
diff --git a/components/script/dom/domexception.rs b/components/script/dom/domexception.rs
index 5f3ac73d3f2b6..136e86434f038 100644
--- a/components/script/dom/domexception.rs
+++ b/components/script/dom/domexception.rs
@@ -157,7 +157,7 @@ impl DOMException {
     }
 }
 
-impl DOMExceptionMethods for DOMException {
+impl DOMExceptionMethods<crate::DomTypeHolder> for DOMException {
     // https://webidl.spec.whatwg.org/#dom-domexception-domexception
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs
index 13b9d14ffe617..b034ad438e45b 100644
--- a/components/script/dom/domimplementation.rs
+++ b/components/script/dom/domimplementation.rs
@@ -52,7 +52,7 @@ impl DOMImplementation {
 }
 
 // https://dom.spec.whatwg.org/#domimplementation
-impl DOMImplementationMethods for DOMImplementation {
+impl DOMImplementationMethods<crate::DomTypeHolder> for DOMImplementation {
     // https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
     fn CreateDocumentType(
         &self,
diff --git a/components/script/dom/dommatrix.rs b/components/script/dom/dommatrix.rs
index 95ad8fc7ef287..b4a6f72b6d150 100644
--- a/components/script/dom/dommatrix.rs
+++ b/components/script/dom/dommatrix.rs
@@ -66,7 +66,7 @@ impl DOMMatrix {
 }
 
 #[allow(non_snake_case)]
-impl DOMMatrixMethods for DOMMatrix {
+impl DOMMatrixMethods<crate::DomTypeHolder> for DOMMatrix {
     // https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-dommatrixreadonly
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/dommatrixreadonly.rs b/components/script/dom/dommatrixreadonly.rs
index 8abb924ec6dff..f5d5ea4b2d97a 100644
--- a/components/script/dom/dommatrixreadonly.rs
+++ b/components/script/dom/dommatrixreadonly.rs
@@ -433,7 +433,7 @@ impl DOMMatrixReadOnly {
 }
 
 #[allow(non_snake_case)]
-impl DOMMatrixReadOnlyMethods for DOMMatrixReadOnly {
+impl DOMMatrixReadOnlyMethods<crate::DomTypeHolder> for DOMMatrixReadOnly {
     // https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-dommatrixreadonly
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs
index c40ed43fd7efd..74d105f68cdd9 100644
--- a/components/script/dom/domparser.rs
+++ b/components/script/dom/domparser.rs
@@ -47,7 +47,7 @@ impl DOMParser {
     }
 }
 
-impl DOMParserMethods for DOMParser {
+impl DOMParserMethods<crate::DomTypeHolder> for DOMParser {
     /// <https://html.spec.whatwg.org/multipage/#dom-domparser-constructor>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/dompoint.rs b/components/script/dom/dompoint.rs
index 0e8d5ad100419..4be2c2cdf8bfe 100644
--- a/components/script/dom/dompoint.rs
+++ b/components/script/dom/dompoint.rs
@@ -65,7 +65,7 @@ impl DOMPoint {
     }
 }
 
-impl DOMPointMethods for DOMPoint {
+impl DOMPointMethods<crate::DomTypeHolder> for DOMPoint {
     // https://drafts.fxtf.org/geometry/#dom-dompointreadonly-dompointreadonly
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/dompointreadonly.rs b/components/script/dom/dompointreadonly.rs
index a52c0d7b65b86..bb926511b96db 100644
--- a/components/script/dom/dompointreadonly.rs
+++ b/components/script/dom/dompointreadonly.rs
@@ -67,7 +67,7 @@ impl DOMPointReadOnly {
 }
 
 #[allow(non_snake_case)]
-impl DOMPointReadOnlyMethods for DOMPointReadOnly {
+impl DOMPointReadOnlyMethods<crate::DomTypeHolder> for DOMPointReadOnly {
     // https://drafts.fxtf.org/geometry/#dom-dompoint-dompoint
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/domquad.rs b/components/script/dom/domquad.rs
index bbcaa11594397..86888845485af 100644
--- a/components/script/dom/domquad.rs
+++ b/components/script/dom/domquad.rs
@@ -66,7 +66,7 @@ impl DOMQuad {
     }
 }
 
-impl DOMQuadMethods for DOMQuad {
+impl DOMQuadMethods<crate::DomTypeHolder> for DOMQuad {
     // https://drafts.fxtf.org/geometry/#dom-domquad-domquad
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/domrect.rs b/components/script/dom/domrect.rs
index 5ab05b94ef4ce..01bf727629d76 100644
--- a/components/script/dom/domrect.rs
+++ b/components/script/dom/domrect.rs
@@ -57,7 +57,7 @@ impl DOMRect {
     }
 }
 
-impl DOMRectMethods for DOMRect {
+impl DOMRectMethods<crate::DomTypeHolder> for DOMRect {
     // https://drafts.fxtf.org/geometry/#dom-domrect-domrect
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/domrectlist.rs b/components/script/dom/domrectlist.rs
index 2762ddab2327f..94e00c2c0c400 100644
--- a/components/script/dom/domrectlist.rs
+++ b/components/script/dom/domrectlist.rs
@@ -48,7 +48,7 @@ impl DOMRectList {
     }
 }
 
-impl DOMRectListMethods for DOMRectList {
+impl DOMRectListMethods<crate::DomTypeHolder> for DOMRectList {
     /// <https://drafts.fxtf.org/geometry/#DOMRectList>
     fn Item(&self, index: u32) -> Option<DomRoot<DOMRect>> {
         self.rects.borrow().get(index as usize).map(Dom::as_rooted)
diff --git a/components/script/dom/domrectreadonly.rs b/components/script/dom/domrectreadonly.rs
index 125122853af22..239dea9060b12 100644
--- a/components/script/dom/domrectreadonly.rs
+++ b/components/script/dom/domrectreadonly.rs
@@ -72,7 +72,7 @@ impl DOMRectReadOnly {
     }
 }
 
-impl DOMRectReadOnlyMethods for DOMRectReadOnly {
+impl DOMRectReadOnlyMethods<crate::DomTypeHolder> for DOMRectReadOnly {
     // https://drafts.fxtf.org/geometry/#dom-domrectreadonly-domrectreadonly
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/domstringlist.rs b/components/script/dom/domstringlist.rs
index 25c770f1e4dbe..f64841232e075 100644
--- a/components/script/dom/domstringlist.rs
+++ b/components/script/dom/domstringlist.rs
@@ -32,7 +32,7 @@ impl DOMStringList {
 }
 
 // https://html.spec.whatwg.org/multipage/#domstringlist
-impl DOMStringListMethods for DOMStringList {
+impl DOMStringListMethods<crate::DomTypeHolder> for DOMStringList {
     // https://html.spec.whatwg.org/multipage/#dom-domstringlist-length
     fn Length(&self) -> u32 {
         self.strings.len() as u32
diff --git a/components/script/dom/domstringmap.rs b/components/script/dom/domstringmap.rs
index 68c5d16a88066..eab7f9d3b1749 100644
--- a/components/script/dom/domstringmap.rs
+++ b/components/script/dom/domstringmap.rs
@@ -34,7 +34,7 @@ impl DOMStringMap {
 }
 
 // https://html.spec.whatwg.org/multipage/#domstringmap
-impl DOMStringMapMethods for DOMStringMap {
+impl DOMStringMapMethods<crate::DomTypeHolder> for DOMStringMap {
     // https://html.spec.whatwg.org/multipage/#dom-domstringmap-removeitem
     fn NamedDeleter(&self, name: DOMString) {
         self.element.delete_custom_attr(name)
diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs
index 4b04549323294..8476dc06cf88e 100644
--- a/components/script/dom/domtokenlist.rs
+++ b/components/script/dom/domtokenlist.rs
@@ -101,7 +101,7 @@ impl DOMTokenList {
 }
 
 /// <https://dom.spec.whatwg.org/#domtokenlist>
-impl DOMTokenListMethods for DOMTokenList {
+impl DOMTokenListMethods<crate::DomTypeHolder> for DOMTokenList {
     /// <https://dom.spec.whatwg.org/#dom-domtokenlist-length>
     fn Length(&self) -> u32 {
         self.attribute()
diff --git a/components/script/dom/dynamicmoduleowner.rs b/components/script/dom/dynamicmoduleowner.rs
index 698ce88ee5a74..889dbae5d8448 100644
--- a/components/script/dom/dynamicmoduleowner.rs
+++ b/components/script/dom/dynamicmoduleowner.rs
@@ -48,7 +48,7 @@ impl DynamicModuleOwner {
     }
 }
 
-impl DynamicModuleOwnerMethods for DynamicModuleOwner {
+impl DynamicModuleOwnerMethods<crate::DomTypeHolder> for DynamicModuleOwner {
     // https://html.spec.whatwg.org/multipage/#integration-with-the-javascript-module-system:import()
     fn Promise(&self) -> Rc<Promise> {
         self.promise.clone()
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 1c6d22c979a64..b3f81cdc6f76f 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -2114,7 +2114,7 @@ impl Element {
     }
 }
 
-impl ElementMethods for Element {
+impl ElementMethods<crate::DomTypeHolder> for Element {
     // https://dom.spec.whatwg.org/#dom-element-namespaceuri
     fn GetNamespaceURI(&self) -> Option<DOMString> {
         Node::namespace_to_string(self.namespace.clone())
diff --git a/components/script/dom/elementinternals.rs b/components/script/dom/elementinternals.rs
index a3ef4d57e9bd6..bf6e9059651d4 100644
--- a/components/script/dom/elementinternals.rs
+++ b/components/script/dom/elementinternals.rs
@@ -183,7 +183,7 @@ impl ElementInternals {
     }
 }
 
-impl ElementInternalsMethods for ElementInternals {
+impl ElementInternalsMethods<crate::DomTypeHolder> for ElementInternals {
     /// <https://html.spec.whatwg.org/multipage#dom-elementinternals-setformvalue>
     fn SetFormValue(
         &self,
diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs
index 1bd0f9f3af86d..f2075f9070812 100644
--- a/components/script/dom/errorevent.rs
+++ b/components/script/dom/errorevent.rs
@@ -102,7 +102,7 @@ impl ErrorEvent {
     }
 }
 
-impl ErrorEventMethods for ErrorEvent {
+impl ErrorEventMethods<crate::DomTypeHolder> for ErrorEvent {
     // https://html.spec.whatwg.org/multipage/#errorevent
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs
index d02a2b79e9307..a591656a69431 100644
--- a/components/script/dom/event.rs
+++ b/components/script/dom/event.rs
@@ -387,7 +387,7 @@ impl Event {
     }
 }
 
-impl EventMethods for Event {
+impl EventMethods<crate::DomTypeHolder> for Event {
     /// <https://dom.spec.whatwg.org/#dom-event-event>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs
index 8e9249fbd3335..504968931dbfe 100644
--- a/components/script/dom/eventsource.rs
+++ b/components/script/dom/eventsource.rs
@@ -530,7 +530,7 @@ impl Drop for EventSource {
     }
 }
 
-impl EventSourceMethods for EventSource {
+impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
     // https://html.spec.whatwg.org/multipage/#dom-eventsource
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs
index b097080bbc4e3..09931ec0a17b7 100644
--- a/components/script/dom/eventtarget.rs
+++ b/components/script/dom/eventtarget.rs
@@ -783,7 +783,7 @@ impl EventTarget {
     }
 }
 
-impl EventTargetMethods for EventTarget {
+impl EventTargetMethods<crate::DomTypeHolder> for EventTarget {
     // https://dom.spec.whatwg.org/#dom-eventtarget-eventtarget
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/extendableevent.rs b/components/script/dom/extendableevent.rs
index 2249afb880d85..c5e0bac0baa82 100644
--- a/components/script/dom/extendableevent.rs
+++ b/components/script/dom/extendableevent.rs
@@ -67,7 +67,7 @@ impl ExtendableEvent {
     }
 }
 
-impl ExtendableEventMethods for ExtendableEvent {
+impl ExtendableEventMethods<crate::DomTypeHolder> for ExtendableEvent {
     // https://w3c.github.io/ServiceWorker/#dom-extendableevent-extendableevent
     fn Constructor(
         worker: &ServiceWorkerGlobalScope,
diff --git a/components/script/dom/extendablemessageevent.rs b/components/script/dom/extendablemessageevent.rs
index 1bad29e3c789a..484fa06cf848e 100644
--- a/components/script/dom/extendablemessageevent.rs
+++ b/components/script/dom/extendablemessageevent.rs
@@ -161,7 +161,7 @@ impl ExtendableMessageEvent {
     }
 }
 
-impl ExtendableMessageEventMethods for ExtendableMessageEvent {
+impl ExtendableMessageEventMethods<crate::DomTypeHolder> for ExtendableMessageEvent {
     /// <https://w3c.github.io/ServiceWorker/#dom-extendablemessageevent-extendablemessageevent>
     fn Constructor(
         worker: &ServiceWorkerGlobalScope,
diff --git a/components/script/dom/fakexrdevice.rs b/components/script/dom/fakexrdevice.rs
index e2d79660833b1..7024aa9dc65f6 100644
--- a/components/script/dom/fakexrdevice.rs
+++ b/components/script/dom/fakexrdevice.rs
@@ -182,7 +182,7 @@ impl From<FakeXRRegionType> for EntityType {
     }
 }
 
-impl FakeXRDeviceMethods for FakeXRDevice {
+impl FakeXRDeviceMethods<crate::DomTypeHolder> for FakeXRDevice {
     /// <https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md>
     fn SetViews(
         &self,
diff --git a/components/script/dom/fakexrinputcontroller.rs b/components/script/dom/fakexrinputcontroller.rs
index 7f620639e16b5..a9bf8038f5eda 100644
--- a/components/script/dom/fakexrinputcontroller.rs
+++ b/components/script/dom/fakexrinputcontroller.rs
@@ -61,7 +61,7 @@ impl FakeXRInputController {
     }
 }
 
-impl FakeXRInputControllerMethods for FakeXRInputController {
+impl FakeXRInputControllerMethods<crate::DomTypeHolder> for FakeXRInputController {
     /// <https://immersive-web.github.io/webxr-test-api/#dom-fakexrinputcontroller-setpointerorigin>
     fn SetPointerOrigin(&self, origin: &FakeXRRigidTransformInit, _emulated: bool) -> Fallible<()> {
         self.send_message(MockInputMsg::SetPointerOrigin(Some(get_origin(origin)?)));
diff --git a/components/script/dom/file.rs b/components/script/dom/file.rs
index 21127331954f4..5fa55ddf4f547 100644
--- a/components/script/dom/file.rs
+++ b/components/script/dom/file.rs
@@ -102,7 +102,7 @@ impl File {
     }
 }
 
-impl FileMethods for File {
+impl FileMethods<crate::DomTypeHolder> for File {
     // https://w3c.github.io/FileAPI/#file-constructor
     #[allow(non_snake_case)]
     fn Constructor(
diff --git a/components/script/dom/filelist.rs b/components/script/dom/filelist.rs
index d2b647273bac8..44afd40f418c8 100644
--- a/components/script/dom/filelist.rs
+++ b/components/script/dom/filelist.rs
@@ -43,7 +43,7 @@ impl FileList {
     }
 }
 
-impl FileListMethods for FileList {
+impl FileListMethods<crate::DomTypeHolder> for FileList {
     // https://w3c.github.io/FileAPI/#dfn-length
     fn Length(&self) -> u32 {
         self.list.len() as u32
diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs
index 20831493de7a3..e8e697eec9030 100644
--- a/components/script/dom/filereader.rs
+++ b/components/script/dom/filereader.rs
@@ -326,7 +326,7 @@ impl FileReader {
     }
 }
 
-impl FileReaderMethods for FileReader {
+impl FileReaderMethods<crate::DomTypeHolder> for FileReader {
     // https://w3c.github.io/FileAPI/#filereaderConstrctr
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/filereadersync.rs b/components/script/dom/filereadersync.rs
index 5ef1babfea7eb..fa312532eb966 100644
--- a/components/script/dom/filereadersync.rs
+++ b/components/script/dom/filereadersync.rs
@@ -51,7 +51,7 @@ impl FileReaderSync {
     }
 }
 
-impl FileReaderSyncMethods for FileReaderSync {
+impl FileReaderSyncMethods<crate::DomTypeHolder> for FileReaderSync {
     /// <https://w3c.github.io/FileAPI/#filereadersyncConstrctr>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/focusevent.rs b/components/script/dom/focusevent.rs
index 11d1997d5aac8..0f9eced513cf0 100644
--- a/components/script/dom/focusevent.rs
+++ b/components/script/dom/focusevent.rs
@@ -96,7 +96,7 @@ impl FocusEvent {
     }
 }
 
-impl FocusEventMethods for FocusEvent {
+impl FocusEventMethods<crate::DomTypeHolder> for FocusEvent {
     // https://w3c.github.io/uievents/#dom-focusevent-focusevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/fontfaceset.rs b/components/script/dom/fontfaceset.rs
index fa83e8708a1cc..ac8cd1baa78d2 100644
--- a/components/script/dom/fontfaceset.rs
+++ b/components/script/dom/fontfaceset.rs
@@ -48,7 +48,7 @@ impl FontFaceSet {
     }
 }
 
-impl FontFaceSetMethods for FontFaceSet {
+impl FontFaceSetMethods<crate::DomTypeHolder> for FontFaceSet {
     /// <https://drafts.csswg.org/css-font-loading/#dom-fontfaceset-ready>
     fn Ready(&self) -> Rc<Promise> {
         self.promise.clone()
diff --git a/components/script/dom/formdata.rs b/components/script/dom/formdata.rs
index b1d4f6af9471c..bcc0f8156c13a 100644
--- a/components/script/dom/formdata.rs
+++ b/components/script/dom/formdata.rs
@@ -68,7 +68,7 @@ impl FormData {
     }
 }
 
-impl FormDataMethods for FormData {
+impl FormDataMethods<crate::DomTypeHolder> for FormData {
     // https://xhr.spec.whatwg.org/#dom-formdata
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/formdataevent.rs b/components/script/dom/formdataevent.rs
index a4f1b5a8513fc..fc1134f0f808c 100644
--- a/components/script/dom/formdataevent.rs
+++ b/components/script/dom/formdataevent.rs
@@ -67,7 +67,7 @@ impl FormDataEvent {
     }
 }
 
-impl FormDataEventMethods for FormDataEvent {
+impl FormDataEventMethods<crate::DomTypeHolder> for FormDataEvent {
     // https://html.spec.whatwg.org/multipage/#formdataevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/gainnode.rs b/components/script/dom/gainnode.rs
index aa03d616cd626..e8f81904fcca4 100644
--- a/components/script/dom/gainnode.rs
+++ b/components/script/dom/gainnode.rs
@@ -92,7 +92,7 @@ impl GainNode {
     }
 }
 
-impl GainNodeMethods for GainNode {
+impl GainNodeMethods<crate::DomTypeHolder> for GainNode {
     // https://webaudio.github.io/web-audio-api/#dom-gainnode-gainnode
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/gamepad.rs b/components/script/dom/gamepad.rs
index c7f78a666beab..ae3d75f603074 100644
--- a/components/script/dom/gamepad.rs
+++ b/components/script/dom/gamepad.rs
@@ -158,7 +158,7 @@ impl Gamepad {
     }
 }
 
-impl GamepadMethods for Gamepad {
+impl GamepadMethods<crate::DomTypeHolder> for Gamepad {
     // https://w3c.github.io/gamepad/#dom-gamepad-id
     fn Id(&self) -> DOMString {
         DOMString::from(self.id.clone())
diff --git a/components/script/dom/gamepadbutton.rs b/components/script/dom/gamepadbutton.rs
index c23b284837990..7ed3ed567285a 100644
--- a/components/script/dom/gamepadbutton.rs
+++ b/components/script/dom/gamepadbutton.rs
@@ -38,7 +38,7 @@ impl GamepadButton {
     }
 }
 
-impl GamepadButtonMethods for GamepadButton {
+impl GamepadButtonMethods<crate::DomTypeHolder> for GamepadButton {
     // https://www.w3.org/TR/gamepad/#widl-GamepadButton-pressed
     fn Pressed(&self) -> bool {
         self.pressed.get()
diff --git a/components/script/dom/gamepadbuttonlist.rs b/components/script/dom/gamepadbuttonlist.rs
index 961f265e37f7a..ef0739ee06069 100644
--- a/components/script/dom/gamepadbuttonlist.rs
+++ b/components/script/dom/gamepadbuttonlist.rs
@@ -31,7 +31,7 @@ impl GamepadButtonList {
     }
 }
 
-impl GamepadButtonListMethods for GamepadButtonList {
+impl GamepadButtonListMethods<crate::DomTypeHolder> for GamepadButtonList {
     // https://w3c.github.io/gamepad/#dom-gamepad-buttons
     fn Length(&self) -> u32 {
         self.list.len() as u32
diff --git a/components/script/dom/gamepadevent.rs b/components/script/dom/gamepadevent.rs
index 1302020511010..ad835e9f1e563 100644
--- a/components/script/dom/gamepadevent.rs
+++ b/components/script/dom/gamepadevent.rs
@@ -87,7 +87,7 @@ impl GamepadEvent {
     }
 }
 
-impl GamepadEventMethods for GamepadEvent {
+impl GamepadEventMethods<crate::DomTypeHolder> for GamepadEvent {
     // https://w3c.github.io/gamepad/#gamepadevent-interface
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/gamepadhapticactuator.rs b/components/script/dom/gamepadhapticactuator.rs
index 10be49dcfee9d..edffeddd90121 100644
--- a/components/script/dom/gamepadhapticactuator.rs
+++ b/components/script/dom/gamepadhapticactuator.rs
@@ -132,7 +132,7 @@ impl GamepadHapticActuator {
     }
 }
 
-impl GamepadHapticActuatorMethods for GamepadHapticActuator {
+impl GamepadHapticActuatorMethods<crate::DomTypeHolder> for GamepadHapticActuator {
     /// <https://www.w3.org/TR/gamepad/#dom-gamepadhapticactuator-effects>
     fn Effects(&self, cx: JSContext, retval: MutableHandleValue) {
         to_frozen_array(self.effects.as_slice(), cx, retval)
diff --git a/components/script/dom/gamepadpose.rs b/components/script/dom/gamepadpose.rs
index d17681b3a0a99..012b1dd767929 100644
--- a/components/script/dom/gamepadpose.rs
+++ b/components/script/dom/gamepadpose.rs
@@ -49,7 +49,7 @@ impl GamepadPose {
     }
 }
 
-impl GamepadPoseMethods for GamepadPose {
+impl GamepadPoseMethods<crate::DomTypeHolder> for GamepadPose {
     // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-position
     fn GetPosition(&self, _cx: JSContext) -> Option<Float32Array> {
         self.position.buffer_to_option()
diff --git a/components/script/dom/gpu.rs b/components/script/dom/gpu.rs
index 753ff82b7ab29..f6302ca59f18c 100644
--- a/components/script/dom/gpu.rs
+++ b/components/script/dom/gpu.rs
@@ -104,7 +104,7 @@ pub fn response_async<T: AsyncWGPUListener + DomObject + 'static>(
     action_sender
 }
 
-impl GPUMethods for GPU {
+impl GPUMethods<crate::DomTypeHolder> for GPU {
     // https://gpuweb.github.io/gpuweb/#dom-gpu-requestadapter
     fn RequestAdapter(
         &self,
diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs
index 9509475144ad3..4fa8d12dfa75c 100644
--- a/components/script/dom/gpuadapter.rs
+++ b/components/script/dom/gpuadapter.rs
@@ -106,7 +106,7 @@ impl Drop for GPUAdapter {
     }
 }
 
-impl GPUAdapterMethods for GPUAdapter {
+impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestdevice>
     fn RequestDevice(
         &self,
diff --git a/components/script/dom/gpuadapterinfo.rs b/components/script/dom/gpuadapterinfo.rs
index a31454185c66f..bb9a9aeb86350 100644
--- a/components/script/dom/gpuadapterinfo.rs
+++ b/components/script/dom/gpuadapterinfo.rs
@@ -34,7 +34,7 @@ impl GPUAdapterInfo {
 }
 
 // TODO: wgpu does not expose right fields right now
-impl GPUAdapterInfoMethods for GPUAdapterInfo {
+impl GPUAdapterInfoMethods<crate::DomTypeHolder> for GPUAdapterInfo {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuadapterinfo-vendor>
     fn Vendor(&self) -> DOMString {
         DOMString::new()
diff --git a/components/script/dom/gpubindgroup.rs b/components/script/dom/gpubindgroup.rs
index 964959e40c02b..7992e3825d0cd 100644
--- a/components/script/dom/gpubindgroup.rs
+++ b/components/script/dom/gpubindgroup.rs
@@ -129,7 +129,7 @@ impl Drop for GPUBindGroup {
     }
 }
 
-impl GPUBindGroupMethods for GPUBindGroup {
+impl GPUBindGroupMethods<crate::DomTypeHolder> for GPUBindGroup {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpubindgrouplayout.rs b/components/script/dom/gpubindgrouplayout.rs
index 4c2d2413a7a12..c09c36ade5892 100644
--- a/components/script/dom/gpubindgrouplayout.rs
+++ b/components/script/dom/gpubindgrouplayout.rs
@@ -126,7 +126,7 @@ impl Drop for GPUBindGroupLayout {
     }
 }
 
-impl GPUBindGroupLayoutMethods for GPUBindGroupLayout {
+impl GPUBindGroupLayoutMethods<crate::DomTypeHolder> for GPUBindGroupLayout {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs
index 0cae783d653ef..e7bddcde8f1ef 100644
--- a/components/script/dom/gpubuffer.rs
+++ b/components/script/dom/gpubuffer.rs
@@ -184,7 +184,7 @@ impl Drop for GPUBuffer {
     }
 }
 
-impl GPUBufferMethods for GPUBuffer {
+impl GPUBufferMethods<crate::DomTypeHolder> for GPUBuffer {
     #[allow(unsafe_code)]
     /// <https://gpuweb.github.io/gpuweb/#dom-gpubuffer-unmap>
     fn Unmap(&self) {
diff --git a/components/script/dom/gpucanvascontext.rs b/components/script/dom/gpucanvascontext.rs
index 1309ca4c32d12..c20f1d1d877d4 100644
--- a/components/script/dom/gpucanvascontext.rs
+++ b/components/script/dom/gpucanvascontext.rs
@@ -341,7 +341,7 @@ impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, GPUCanvasContext> {
     }
 }
 
-impl GPUCanvasContextMethods for GPUCanvasContext {
+impl GPUCanvasContextMethods<crate::DomTypeHolder> for GPUCanvasContext {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpucanvascontext-canvas>
     fn Canvas(&self) -> HTMLCanvasElementOrOffscreenCanvas {
         self.canvas.clone()
diff --git a/components/script/dom/gpucommandbuffer.rs b/components/script/dom/gpucommandbuffer.rs
index 7bcff2d9000b8..120af69a4806a 100644
--- a/components/script/dom/gpucommandbuffer.rs
+++ b/components/script/dom/gpucommandbuffer.rs
@@ -75,7 +75,7 @@ impl GPUCommandBuffer {
     }
 }
 
-impl GPUCommandBufferMethods for GPUCommandBuffer {
+impl GPUCommandBufferMethods<crate::DomTypeHolder> for GPUCommandBuffer {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpucommandencoder.rs b/components/script/dom/gpucommandencoder.rs
index 8b62cbb80305f..9dcec03540c37 100644
--- a/components/script/dom/gpucommandencoder.rs
+++ b/components/script/dom/gpucommandencoder.rs
@@ -110,7 +110,7 @@ impl GPUCommandEncoder {
     }
 }
 
-impl GPUCommandEncoderMethods for GPUCommandEncoder {
+impl GPUCommandEncoderMethods<crate::DomTypeHolder> for GPUCommandEncoder {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpucompilationinfo.rs b/components/script/dom/gpucompilationinfo.rs
index a54b3e81e41c4..4bfa849d49ec7 100644
--- a/components/script/dom/gpucompilationinfo.rs
+++ b/components/script/dom/gpucompilationinfo.rs
@@ -56,7 +56,7 @@ impl GPUCompilationInfo {
     }
 }
 
-impl GPUCompilationInfoMethods for GPUCompilationInfo {
+impl GPUCompilationInfoMethods<crate::DomTypeHolder> for GPUCompilationInfo {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpucompilationinfo-messages>
     fn Messages(&self, cx: JSContext, retval: MutableHandleValue) {
         to_frozen_array(self.msg.as_slice(), cx, retval)
diff --git a/components/script/dom/gpucompilationmessage.rs b/components/script/dom/gpucompilationmessage.rs
index cf5249651538c..dbdf87bdedefa 100644
--- a/components/script/dom/gpucompilationmessage.rs
+++ b/components/script/dom/gpucompilationmessage.rs
@@ -77,7 +77,7 @@ impl GPUCompilationMessage {
     }
 }
 
-impl GPUCompilationMessageMethods for GPUCompilationMessage {
+impl GPUCompilationMessageMethods<crate::DomTypeHolder> for GPUCompilationMessage {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpucompilationmessage-message>
     fn Message(&self) -> DOMString {
         self.message.to_owned()
diff --git a/components/script/dom/gpucomputepassencoder.rs b/components/script/dom/gpucomputepassencoder.rs
index ccdfbb05f99d9..e75157b32fc64 100644
--- a/components/script/dom/gpucomputepassencoder.rs
+++ b/components/script/dom/gpucomputepassencoder.rs
@@ -63,7 +63,7 @@ impl GPUComputePassEncoder {
     }
 }
 
-impl GPUComputePassEncoderMethods for GPUComputePassEncoder {
+impl GPUComputePassEncoderMethods<crate::DomTypeHolder> for GPUComputePassEncoder {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpucomputepipeline.rs b/components/script/dom/gpucomputepipeline.rs
index cca5e4141917f..4d905126c7182 100644
--- a/components/script/dom/gpucomputepipeline.rs
+++ b/components/script/dom/gpucomputepipeline.rs
@@ -101,7 +101,7 @@ impl GPUComputePipeline {
     }
 }
 
-impl GPUComputePipelineMethods for GPUComputePipeline {
+impl GPUComputePipelineMethods<crate::DomTypeHolder> for GPUComputePipeline {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs
index 51361118f8d6d..b62f800f3e6c3 100644
--- a/components/script/dom/gpudevice.rs
+++ b/components/script/dom/gpudevice.rs
@@ -377,7 +377,7 @@ impl GPUDevice {
     }
 }
 
-impl GPUDeviceMethods for GPUDevice {
+impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-features>
     fn Features(&self) -> DomRoot<GPUSupportedFeatures> {
         DomRoot::from_ref(&self.features)
diff --git a/components/script/dom/gpudevicelostinfo.rs b/components/script/dom/gpudevicelostinfo.rs
index 1616e9d71692b..3219c0fe20240 100644
--- a/components/script/dom/gpudevicelostinfo.rs
+++ b/components/script/dom/gpudevicelostinfo.rs
@@ -41,7 +41,7 @@ impl GPUDeviceLostInfo {
     }
 }
 
-impl GPUDeviceLostInfoMethods for GPUDeviceLostInfo {
+impl GPUDeviceLostInfoMethods<crate::DomTypeHolder> for GPUDeviceLostInfo {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpudevicelostinfo-message>
     fn Message(&self) -> DOMString {
         self.message.clone()
diff --git a/components/script/dom/gpuerror.rs b/components/script/dom/gpuerror.rs
index 7346454375350..20ecff210d639 100644
--- a/components/script/dom/gpuerror.rs
+++ b/components/script/dom/gpuerror.rs
@@ -72,7 +72,7 @@ impl GPUError {
     }
 }
 
-impl GPUErrorMethods for GPUError {
+impl GPUErrorMethods<crate::DomTypeHolder> for GPUError {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuerror-message>
     fn Message(&self) -> DOMString {
         self.message.clone()
diff --git a/components/script/dom/gpuinternalerror.rs b/components/script/dom/gpuinternalerror.rs
index 224319298fb69..4be5be9a22e7b 100644
--- a/components/script/dom/gpuinternalerror.rs
+++ b/components/script/dom/gpuinternalerror.rs
@@ -40,7 +40,7 @@ impl GPUInternalError {
     }
 }
 
-impl GPUInternalErrorMethods for GPUInternalError {
+impl GPUInternalErrorMethods<crate::DomTypeHolder> for GPUInternalError {
     /// <https://gpuweb.github.io/gpuweb/#dom-GPUInternalError-GPUInternalError>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/gpuoutofmemoryerror.rs b/components/script/dom/gpuoutofmemoryerror.rs
index 588bfc86cfcd6..22763e89c4823 100644
--- a/components/script/dom/gpuoutofmemoryerror.rs
+++ b/components/script/dom/gpuoutofmemoryerror.rs
@@ -40,7 +40,7 @@ impl GPUOutOfMemoryError {
     }
 }
 
-impl GPUOutOfMemoryErrorMethods for GPUOutOfMemoryError {
+impl GPUOutOfMemoryErrorMethods<crate::DomTypeHolder> for GPUOutOfMemoryError {
     /// <https://gpuweb.github.io/gpuweb/#dom-GPUOutOfMemoryError-GPUOutOfMemoryError>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/gpupipelineerror.rs b/components/script/dom/gpupipelineerror.rs
index 23b438d22fa7e..d8a4bb5a58785 100644
--- a/components/script/dom/gpupipelineerror.rs
+++ b/components/script/dom/gpupipelineerror.rs
@@ -55,7 +55,7 @@ impl GPUPipelineError {
     }
 }
 
-impl GPUPipelineErrorMethods for GPUPipelineError {
+impl GPUPipelineErrorMethods<crate::DomTypeHolder> for GPUPipelineError {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpupipelineerror-constructor>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/gpupipelinelayout.rs b/components/script/dom/gpupipelinelayout.rs
index c97cee67b5b16..c1cbbdb72ab0d 100644
--- a/components/script/dom/gpupipelinelayout.rs
+++ b/components/script/dom/gpupipelinelayout.rs
@@ -114,7 +114,7 @@ impl GPUPipelineLayout {
     }
 }
 
-impl GPUPipelineLayoutMethods for GPUPipelineLayout {
+impl GPUPipelineLayoutMethods<crate::DomTypeHolder> for GPUPipelineLayout {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpuqueryset.rs b/components/script/dom/gpuqueryset.rs
index 51f859b6e13e4..40e734f9eecbf 100644
--- a/components/script/dom/gpuqueryset.rs
+++ b/components/script/dom/gpuqueryset.rs
@@ -17,7 +17,7 @@ pub struct GPUQuerySet {
 }
 
 // TODO: wgpu does not expose right fields right now
-impl GPUQuerySetMethods for GPUQuerySet {
+impl GPUQuerySetMethods<crate::DomTypeHolder> for GPUQuerySet {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuqueryset-destroy>
     fn Destroy(&self) {
         todo!()
diff --git a/components/script/dom/gpuqueue.rs b/components/script/dom/gpuqueue.rs
index f371743e68108..4098356799073 100644
--- a/components/script/dom/gpuqueue.rs
+++ b/components/script/dom/gpuqueue.rs
@@ -64,7 +64,7 @@ impl GPUQueue {
     }
 }
 
-impl GPUQueueMethods for GPUQueue {
+impl GPUQueueMethods<crate::DomTypeHolder> for GPUQueue {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpurenderbundle.rs b/components/script/dom/gpurenderbundle.rs
index 92827df6ab73c..aae120b970b37 100644
--- a/components/script/dom/gpurenderbundle.rs
+++ b/components/script/dom/gpurenderbundle.rs
@@ -66,7 +66,7 @@ impl GPURenderBundle {
     }
 }
 
-impl GPURenderBundleMethods for GPURenderBundle {
+impl GPURenderBundleMethods<crate::DomTypeHolder> for GPURenderBundle {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpurenderbundleencoder.rs b/components/script/dom/gpurenderbundleencoder.rs
index 9a494a1d628da..fdaf6fa534e24 100644
--- a/components/script/dom/gpurenderbundleencoder.rs
+++ b/components/script/dom/gpurenderbundleencoder.rs
@@ -124,7 +124,7 @@ impl GPURenderBundleEncoder {
     }
 }
 
-impl GPURenderBundleEncoderMethods for GPURenderBundleEncoder {
+impl GPURenderBundleEncoderMethods<crate::DomTypeHolder> for GPURenderBundleEncoder {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpurenderpassencoder.rs b/components/script/dom/gpurenderpassencoder.rs
index a2449bc88787e..36d425a4789e9 100644
--- a/components/script/dom/gpurenderpassencoder.rs
+++ b/components/script/dom/gpurenderpassencoder.rs
@@ -79,7 +79,7 @@ impl GPURenderPassEncoder {
     }
 }
 
-impl GPURenderPassEncoderMethods for GPURenderPassEncoder {
+impl GPURenderPassEncoderMethods<crate::DomTypeHolder> for GPURenderPassEncoder {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpurenderpipeline.rs b/components/script/dom/gpurenderpipeline.rs
index 96de0ffd92528..0cf8754ecbf5a 100644
--- a/components/script/dom/gpurenderpipeline.rs
+++ b/components/script/dom/gpurenderpipeline.rs
@@ -91,7 +91,7 @@ impl GPURenderPipeline {
     }
 }
 
-impl GPURenderPipelineMethods for GPURenderPipeline {
+impl GPURenderPipelineMethods<crate::DomTypeHolder> for GPURenderPipeline {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpusampler.rs b/components/script/dom/gpusampler.rs
index e79ea6af59163..ad7aa3e8b898c 100644
--- a/components/script/dom/gpusampler.rs
+++ b/components/script/dom/gpusampler.rs
@@ -118,7 +118,7 @@ impl GPUSampler {
     }
 }
 
-impl GPUSamplerMethods for GPUSampler {
+impl GPUSamplerMethods<crate::DomTypeHolder> for GPUSampler {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpushadermodule.rs b/components/script/dom/gpushadermodule.rs
index f08c91e32bb7c..4febc7586378c 100644
--- a/components/script/dom/gpushadermodule.rs
+++ b/components/script/dom/gpushadermodule.rs
@@ -109,7 +109,7 @@ impl GPUShaderModule {
     }
 }
 
-impl GPUShaderModuleMethods for GPUShaderModule {
+impl GPUShaderModuleMethods<crate::DomTypeHolder> for GPUShaderModule {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpusupportedfeatures.rs b/components/script/dom/gpusupportedfeatures.rs
index cafa8d879085b..797b2635925f6 100644
--- a/components/script/dom/gpusupportedfeatures.rs
+++ b/components/script/dom/gpusupportedfeatures.rs
@@ -125,7 +125,7 @@ impl GPUSupportedFeatures {
     }
 }
 
-impl GPUSupportedFeaturesMethods for GPUSupportedFeatures {
+impl GPUSupportedFeaturesMethods<crate::DomTypeHolder> for GPUSupportedFeatures {
     fn Size(&self) -> u32 {
         self.internal.size()
     }
diff --git a/components/script/dom/gpusupportedlimits.rs b/components/script/dom/gpusupportedlimits.rs
index f86dd5aaf20fc..bbad05face0c1 100644
--- a/components/script/dom/gpusupportedlimits.rs
+++ b/components/script/dom/gpusupportedlimits.rs
@@ -34,7 +34,7 @@ impl GPUSupportedLimits {
     }
 }
 
-impl GPUSupportedLimitsMethods for GPUSupportedLimits {
+impl GPUSupportedLimitsMethods<crate::DomTypeHolder> for GPUSupportedLimits {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpusupportedlimits-maxtexturedimension1d>
     fn MaxTextureDimension1D(&self) -> u32 {
         self.limits.max_texture_dimension_1d
diff --git a/components/script/dom/gputexture.rs b/components/script/dom/gputexture.rs
index 530af51666df1..50913734ad5a2 100644
--- a/components/script/dom/gputexture.rs
+++ b/components/script/dom/gputexture.rs
@@ -160,7 +160,7 @@ impl GPUTexture {
     }
 }
 
-impl GPUTextureMethods for GPUTexture {
+impl GPUTextureMethods<crate::DomTypeHolder> for GPUTexture {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gputextureview.rs b/components/script/dom/gputextureview.rs
index b7e703d670a4c..3c8d484fca3ee 100644
--- a/components/script/dom/gputextureview.rs
+++ b/components/script/dom/gputextureview.rs
@@ -66,7 +66,7 @@ impl GPUTextureView {
     }
 }
 
-impl GPUTextureViewMethods for GPUTextureView {
+impl GPUTextureViewMethods<crate::DomTypeHolder> for GPUTextureView {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/gpuuncapturederrorevent.rs b/components/script/dom/gpuuncapturederrorevent.rs
index 262c8207d7ec8..0ee3871d98dea 100644
--- a/components/script/dom/gpuuncapturederrorevent.rs
+++ b/components/script/dom/gpuuncapturederrorevent.rs
@@ -68,7 +68,7 @@ impl GPUUncapturedErrorEvent {
     }
 }
 
-impl GPUUncapturedErrorEventMethods for GPUUncapturedErrorEvent {
+impl GPUUncapturedErrorEventMethods<crate::DomTypeHolder> for GPUUncapturedErrorEvent {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuuncapturederrorevent-gpuuncapturederrorevent>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/gpuvalidationerror.rs b/components/script/dom/gpuvalidationerror.rs
index b02623134ffae..f29e5bc4e5bf4 100644
--- a/components/script/dom/gpuvalidationerror.rs
+++ b/components/script/dom/gpuvalidationerror.rs
@@ -40,7 +40,7 @@ impl GPUValidationError {
     }
 }
 
-impl GPUValidationErrorMethods for GPUValidationError {
+impl GPUValidationErrorMethods<crate::DomTypeHolder> for GPUValidationError {
     /// <https://gpuweb.github.io/gpuweb/#dom-gpuvalidationerror-gpuvalidationerror>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/hashchangeevent.rs b/components/script/dom/hashchangeevent.rs
index e39ede9870b3c..001eb6497cf62 100644
--- a/components/script/dom/hashchangeevent.rs
+++ b/components/script/dom/hashchangeevent.rs
@@ -91,7 +91,7 @@ impl HashChangeEvent {
     }
 }
 
-impl HashChangeEventMethods for HashChangeEvent {
+impl HashChangeEventMethods<crate::DomTypeHolder> for HashChangeEvent {
     // https://html.spec.whatwg.org/multipage/#hashchangeevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/headers.rs b/components/script/dom/headers.rs
index 3bc50df5ce5ef..65e8239327418 100644
--- a/components/script/dom/headers.rs
+++ b/components/script/dom/headers.rs
@@ -65,7 +65,7 @@ impl Headers {
     }
 }
 
-impl HeadersMethods for Headers {
+impl HeadersMethods<crate::DomTypeHolder> for Headers {
     // https://fetch.spec.whatwg.org/#dom-headers
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs
index 039bf15d5ed86..fb082acd9d71b 100644
--- a/components/script/dom/history.rs
+++ b/components/script/dom/history.rs
@@ -287,7 +287,7 @@ impl History {
     }
 }
 
-impl HistoryMethods for History {
+impl HistoryMethods<crate::DomTypeHolder> for History {
     /// <https://html.spec.whatwg.org/multipage/#dom-history-state>
     fn GetState(&self, _cx: JSContext, mut retval: MutableHandleValue) -> Fallible<()> {
         if !self.window.Document().is_fully_active() {
diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs
index bf0db25713410..afdfa7bb68dea 100644
--- a/components/script/dom/htmlanchorelement.rs
+++ b/components/script/dom/htmlanchorelement.rs
@@ -160,7 +160,7 @@ impl VirtualMethods for HTMLAnchorElement {
     }
 }
 
-impl HTMLAnchorElementMethods for HTMLAnchorElement {
+impl HTMLAnchorElementMethods<crate::DomTypeHolder> for HTMLAnchorElement {
     // https://html.spec.whatwg.org/multipage/#dom-a-text
     fn Text(&self) -> DOMString {
         self.upcast::<Node>().GetTextContent().unwrap()
diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs
index f42a769a18e36..0586b0875d710 100644
--- a/components/script/dom/htmlareaelement.rs
+++ b/components/script/dom/htmlareaelement.rs
@@ -332,7 +332,7 @@ impl VirtualMethods for HTMLAreaElement {
     }
 }
 
-impl HTMLAreaElementMethods for HTMLAreaElement {
+impl HTMLAreaElementMethods<crate::DomTypeHolder> for HTMLAreaElement {
     // https://html.spec.whatwg.org/multipage/#attr-hyperlink-target
     make_getter!(Target, "target");
 
diff --git a/components/script/dom/htmlaudioelement.rs b/components/script/dom/htmlaudioelement.rs
index b9140f9c2d392..288782550c229 100644
--- a/components/script/dom/htmlaudioelement.rs
+++ b/components/script/dom/htmlaudioelement.rs
@@ -55,7 +55,7 @@ impl HTMLAudioElement {
     }
 }
 
-impl HTMLAudioElementMethods for HTMLAudioElement {
+impl HTMLAudioElementMethods<crate::DomTypeHolder> for HTMLAudioElement {
     // https://html.spec.whatwg.org/multipage/#dom-audio
     fn Audio(
         window: &Window,
diff --git a/components/script/dom/htmlbaseelement.rs b/components/script/dom/htmlbaseelement.rs
index e87d8b58fc57c..9618eebacd1b6 100644
--- a/components/script/dom/htmlbaseelement.rs
+++ b/components/script/dom/htmlbaseelement.rs
@@ -80,7 +80,7 @@ impl HTMLBaseElement {
     }
 }
 
-impl HTMLBaseElementMethods for HTMLBaseElement {
+impl HTMLBaseElementMethods<crate::DomTypeHolder> for HTMLBaseElement {
     // https://html.spec.whatwg.org/multipage/#dom-base-href
     fn Href(&self) -> DOMString {
         // Step 1.
diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs
index e85eb40790047..5bb650973c756 100644
--- a/components/script/dom/htmlbodyelement.rs
+++ b/components/script/dom/htmlbodyelement.rs
@@ -73,7 +73,7 @@ impl HTMLBodyElement {
     }
 }
 
-impl HTMLBodyElementMethods for HTMLBodyElement {
+impl HTMLBodyElementMethods<crate::DomTypeHolder> for HTMLBodyElement {
     // https://html.spec.whatwg.org/multipage/#dom-body-bgcolor
     make_getter!(BgColor, "bgcolor");
 
diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs
index 0fc017a170741..75e8be38b17e5 100644
--- a/components/script/dom/htmlbuttonelement.rs
+++ b/components/script/dom/htmlbuttonelement.rs
@@ -93,7 +93,7 @@ impl HTMLButtonElement {
     }
 }
 
-impl HTMLButtonElementMethods for HTMLButtonElement {
+impl HTMLButtonElementMethods<crate::DomTypeHolder> for HTMLButtonElement {
     // https://html.spec.whatwg.org/multipage/#dom-fe-disabled
     make_bool_getter!(Disabled, "disabled");
 
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index bb3109771f9ae..ed49a7426146b 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -339,7 +339,7 @@ impl HTMLCanvasElement {
     }
 }
 
-impl HTMLCanvasElementMethods for HTMLCanvasElement {
+impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
     // https://html.spec.whatwg.org/multipage/#dom-canvas-width
     make_uint_getter!(Width, "width", DEFAULT_WIDTH);
 
diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs
index 0dc1eae0a12d5..dc95d644d16c4 100644
--- a/components/script/dom/htmlcollection.rs
+++ b/components/script/dom/htmlcollection.rs
@@ -315,7 +315,7 @@ impl HTMLCollection {
     }
 }
 
-impl HTMLCollectionMethods for HTMLCollection {
+impl HTMLCollectionMethods<crate::DomTypeHolder> for HTMLCollection {
     /// <https://dom.spec.whatwg.org/#dom-htmlcollection-length>
     fn Length(&self) -> u32 {
         self.validate_cache();
diff --git a/components/script/dom/htmldataelement.rs b/components/script/dom/htmldataelement.rs
index c393ef376c34b..5aadd1c8e3a43 100644
--- a/components/script/dom/htmldataelement.rs
+++ b/components/script/dom/htmldataelement.rs
@@ -47,7 +47,7 @@ impl HTMLDataElement {
     }
 }
 
-impl HTMLDataElementMethods for HTMLDataElement {
+impl HTMLDataElementMethods<crate::DomTypeHolder> for HTMLDataElement {
     // https://html.spec.whatwg.org/multipage/#dom-data-value
     make_getter!(Value, "value");
 
diff --git a/components/script/dom/htmldatalistelement.rs b/components/script/dom/htmldatalistelement.rs
index 3a5947e218a34..e27d6aa969ce8 100644
--- a/components/script/dom/htmldatalistelement.rs
+++ b/components/script/dom/htmldatalistelement.rs
@@ -52,7 +52,7 @@ impl HTMLDataListElement {
     }
 }
 
-impl HTMLDataListElementMethods for HTMLDataListElement {
+impl HTMLDataListElementMethods<crate::DomTypeHolder> for HTMLDataListElement {
     // https://html.spec.whatwg.org/multipage/#dom-datalist-options
     fn Options(&self) -> DomRoot<HTMLCollection> {
         #[derive(JSTraceable, MallocSizeOf)]
diff --git a/components/script/dom/htmldetailselement.rs b/components/script/dom/htmldetailselement.rs
index a1086a865157a..44a8a8fe63a9f 100644
--- a/components/script/dom/htmldetailselement.rs
+++ b/components/script/dom/htmldetailselement.rs
@@ -63,7 +63,7 @@ impl HTMLDetailsElement {
     }
 }
 
-impl HTMLDetailsElementMethods for HTMLDetailsElement {
+impl HTMLDetailsElementMethods<crate::DomTypeHolder> for HTMLDetailsElement {
     // https://html.spec.whatwg.org/multipage/#dom-details-open
     make_bool_getter!(Open, "open");
 
diff --git a/components/script/dom/htmldialogelement.rs b/components/script/dom/htmldialogelement.rs
index ee52cbfb814a6..860072566d788 100644
--- a/components/script/dom/htmldialogelement.rs
+++ b/components/script/dom/htmldialogelement.rs
@@ -55,7 +55,7 @@ impl HTMLDialogElement {
     }
 }
 
-impl HTMLDialogElementMethods for HTMLDialogElement {
+impl HTMLDialogElementMethods<crate::DomTypeHolder> for HTMLDialogElement {
     // https://html.spec.whatwg.org/multipage/#dom-dialog-open
     make_bool_getter!(Open, "open");
 
diff --git a/components/script/dom/htmldivelement.rs b/components/script/dom/htmldivelement.rs
index bc028c1d09ded..4bb69f863d28c 100644
--- a/components/script/dom/htmldivelement.rs
+++ b/components/script/dom/htmldivelement.rs
@@ -47,7 +47,7 @@ impl HTMLDivElement {
     }
 }
 
-impl HTMLDivElementMethods for HTMLDivElement {
+impl HTMLDivElementMethods<crate::DomTypeHolder> for HTMLDivElement {
     // https://html.spec.whatwg.org/multipage/#dom-div-align
     make_getter!(Align, "align");
 
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index 697e5833a4291..5f96e38851fdc 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -135,7 +135,7 @@ impl HTMLElement {
     }
 }
 
-impl HTMLElementMethods for HTMLElement {
+impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
     // https://html.spec.whatwg.org/multipage/#the-style-attribute
     fn Style(&self) -> DomRoot<CSSStyleDeclaration> {
         self.style_decl.or_init(|| {
diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs
index b0a253e869bac..d6f4f95fe6bbd 100644
--- a/components/script/dom/htmlfieldsetelement.rs
+++ b/components/script/dom/htmlfieldsetelement.rs
@@ -85,7 +85,7 @@ impl HTMLFieldSetElement {
     }
 }
 
-impl HTMLFieldSetElementMethods for HTMLFieldSetElement {
+impl HTMLFieldSetElementMethods<crate::DomTypeHolder> for HTMLFieldSetElement {
     // https://html.spec.whatwg.org/multipage/#dom-fieldset-elements
     fn Elements(&self) -> DomRoot<HTMLCollection> {
         #[derive(JSTraceable, MallocSizeOf)]
diff --git a/components/script/dom/htmlfontelement.rs b/components/script/dom/htmlfontelement.rs
index 13d9cd41307fa..b670ff4971f03 100644
--- a/components/script/dom/htmlfontelement.rs
+++ b/components/script/dom/htmlfontelement.rs
@@ -90,7 +90,7 @@ impl HTMLFontElement {
     }
 }
 
-impl HTMLFontElementMethods for HTMLFontElement {
+impl HTMLFontElementMethods<crate::DomTypeHolder> for HTMLFontElement {
     // https://html.spec.whatwg.org/multipage/#dom-font-color
     make_getter!(Color, "color");
 
diff --git a/components/script/dom/htmlformcontrolscollection.rs b/components/script/dom/htmlformcontrolscollection.rs
index 271eb2041506f..4c037fd0632de 100644
--- a/components/script/dom/htmlformcontrolscollection.rs
+++ b/components/script/dom/htmlformcontrolscollection.rs
@@ -52,7 +52,7 @@ impl HTMLFormControlsCollection {
     }
 }
 
-impl HTMLFormControlsCollectionMethods for HTMLFormControlsCollection {
+impl HTMLFormControlsCollectionMethods<crate::DomTypeHolder> for HTMLFormControlsCollection {
     // FIXME: This shouldn't need to be implemented here since HTMLCollection (the parent of
     // HTMLFormControlsCollection) implements Length
     // https://dom.spec.whatwg.org/#dom-htmlcollection-length
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 3be435edcff06..4fe3785d470cb 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -203,7 +203,7 @@ impl HTMLFormElement {
     }
 }
 
-impl HTMLFormElementMethods for HTMLFormElement {
+impl HTMLFormElementMethods<crate::DomTypeHolder> for HTMLFormElement {
     // https://html.spec.whatwg.org/multipage/#dom-form-acceptcharset
     make_getter!(AcceptCharset, "accept-charset");
 
diff --git a/components/script/dom/htmlframesetelement.rs b/components/script/dom/htmlframesetelement.rs
index 37e81ff2f0a58..c7d401411f730 100644
--- a/components/script/dom/htmlframesetelement.rs
+++ b/components/script/dom/htmlframesetelement.rs
@@ -52,7 +52,7 @@ impl HTMLFrameSetElement {
     }
 }
 
-impl HTMLFrameSetElementMethods for HTMLFrameSetElement {
+impl HTMLFrameSetElementMethods<crate::DomTypeHolder> for HTMLFrameSetElement {
     // https://html.spec.whatwg.org/multipage/#windoweventhandlers
     window_event_handlers!(ForwardToWindow);
 }
diff --git a/components/script/dom/htmlhrelement.rs b/components/script/dom/htmlhrelement.rs
index 24f86f946746d..bf9cf8e79a0ed 100644
--- a/components/script/dom/htmlhrelement.rs
+++ b/components/script/dom/htmlhrelement.rs
@@ -52,7 +52,7 @@ impl HTMLHRElement {
     }
 }
 
-impl HTMLHRElementMethods for HTMLHRElement {
+impl HTMLHRElementMethods<crate::DomTypeHolder> for HTMLHRElement {
     // https://html.spec.whatwg.org/multipage/#dom-hr-align
     make_getter!(Align, "align");
 
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index d26cf6297f2b4..f6d555da1ad06 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -549,7 +549,7 @@ impl HTMLIFrameElementLayoutMethods for LayoutDom<'_, HTMLIFrameElement> {
     }
 }
 
-impl HTMLIFrameElementMethods for HTMLIFrameElement {
+impl HTMLIFrameElementMethods<crate::DomTypeHolder> for HTMLIFrameElement {
     // https://html.spec.whatwg.org/multipage/#dom-iframe-src
     make_url_getter!(Src, "src");
 
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index 61f4400a5547b..2bb1277c987c4 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -1534,7 +1534,7 @@ fn get_correct_referrerpolicy_from_raw_token(token: &DOMString) -> DOMString {
 }
 
 #[allow(non_snake_case)]
-impl HTMLImageElementMethods for HTMLImageElement {
+impl HTMLImageElementMethods<crate::DomTypeHolder> for HTMLImageElement {
     // https://html.spec.whatwg.org/multipage/#dom-image
     fn Image(
         window: &Window,
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 08aacca46e175..5eae0866e1ad3 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -1131,7 +1131,7 @@ impl TextControlElement for HTMLInputElement {
 }
 
 #[allow(non_snake_case)]
-impl HTMLInputElementMethods for HTMLInputElement {
+impl HTMLInputElementMethods<crate::DomTypeHolder> for HTMLInputElement {
     // https://html.spec.whatwg.org/multipage/#dom-input-accept
     make_getter!(Accept, "accept");
 
diff --git a/components/script/dom/htmllabelelement.rs b/components/script/dom/htmllabelelement.rs
index 9fc8b3eb2f203..c1f7a4d663cd6 100644
--- a/components/script/dom/htmllabelelement.rs
+++ b/components/script/dom/htmllabelelement.rs
@@ -83,7 +83,7 @@ impl Activatable for HTMLLabelElement {
     }
 }
 
-impl HTMLLabelElementMethods for HTMLLabelElement {
+impl HTMLLabelElementMethods<crate::DomTypeHolder> for HTMLLabelElement {
     // https://html.spec.whatwg.org/multipage/#dom-fae-form
     fn GetForm(&self) -> Option<DomRoot<HTMLFormElement>> {
         self.form_owner()
diff --git a/components/script/dom/htmllegendelement.rs b/components/script/dom/htmllegendelement.rs
index 8d5029b69fa8e..7d21ebf65cb51 100644
--- a/components/script/dom/htmllegendelement.rs
+++ b/components/script/dom/htmllegendelement.rs
@@ -86,7 +86,7 @@ impl VirtualMethods for HTMLLegendElement {
     }
 }
 
-impl HTMLLegendElementMethods for HTMLLegendElement {
+impl HTMLLegendElementMethods<crate::DomTypeHolder> for HTMLLegendElement {
     // https://html.spec.whatwg.org/multipage/#dom-legend-form
     fn GetForm(&self) -> Option<DomRoot<HTMLFormElement>> {
         let parent = self.upcast::<Node>().GetParentElement()?;
diff --git a/components/script/dom/htmllielement.rs b/components/script/dom/htmllielement.rs
index b86db3afef182..1ce637d408963 100644
--- a/components/script/dom/htmllielement.rs
+++ b/components/script/dom/htmllielement.rs
@@ -50,7 +50,7 @@ impl HTMLLIElement {
     }
 }
 
-impl HTMLLIElementMethods for HTMLLIElement {
+impl HTMLLIElementMethods<crate::DomTypeHolder> for HTMLLIElement {
     // https://html.spec.whatwg.org/multipage/#dom-li-value
     make_int_getter!(Value, "value");
 
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index 140471071a859..f34f508c71c60 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -517,7 +517,7 @@ impl StylesheetOwner for HTMLLinkElement {
     }
 }
 
-impl HTMLLinkElementMethods for HTMLLinkElement {
+impl HTMLLinkElementMethods<crate::DomTypeHolder> for HTMLLinkElement {
     // https://html.spec.whatwg.org/multipage/#dom-link-href
     make_url_getter!(Href, "href");
 
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index e7aa9c274e48a..b30fa3d4b2246 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -2068,7 +2068,7 @@ impl Drop for HTMLMediaElement {
     }
 }
 
-impl HTMLMediaElementMethods for HTMLMediaElement {
+impl HTMLMediaElementMethods<crate::DomTypeHolder> for HTMLMediaElement {
     // https://html.spec.whatwg.org/multipage/#dom-media-networkstate
     fn NetworkState(&self) -> u16 {
         self.network_state.get() as u16
diff --git a/components/script/dom/htmlmenuelement.rs b/components/script/dom/htmlmenuelement.rs
index 23395728b32b8..292124e1b48be 100644
--- a/components/script/dom/htmlmenuelement.rs
+++ b/components/script/dom/htmlmenuelement.rs
@@ -46,7 +46,7 @@ impl HTMLMenuElement {
     }
 }
 
-impl HTMLMenuElementMethods for HTMLMenuElement {
+impl HTMLMenuElementMethods<crate::DomTypeHolder> for HTMLMenuElement {
     // spec just mandates that compact reflects the content attribute,
     // with no other semantics. Layout could use it to
     // change line spacing, but nothing requires it to do so.
diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs
index 3f4e6d2b53bd4..e3df38f9f914f 100644
--- a/components/script/dom/htmlmetaelement.rs
+++ b/components/script/dom/htmlmetaelement.rs
@@ -224,7 +224,7 @@ impl HTMLMetaElement {
     }
 }
 
-impl HTMLMetaElementMethods for HTMLMetaElement {
+impl HTMLMetaElementMethods<crate::DomTypeHolder> for HTMLMetaElement {
     // https://html.spec.whatwg.org/multipage/#dom-meta-name
     make_getter!(Name, "name");
 
diff --git a/components/script/dom/htmlmeterelement.rs b/components/script/dom/htmlmeterelement.rs
index d316103308c10..df7ffa2c6af58 100644
--- a/components/script/dom/htmlmeterelement.rs
+++ b/components/script/dom/htmlmeterelement.rs
@@ -58,7 +58,7 @@ impl HTMLMeterElement {
     }
 }
 
-impl HTMLMeterElementMethods for HTMLMeterElement {
+impl HTMLMeterElementMethods<crate::DomTypeHolder> for HTMLMeterElement {
     // https://html.spec.whatwg.org/multipage/#dom-lfe-labels
     make_labels_getter!(Labels, labels_node_list);
 
diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs
index e0cea43155bef..591a330ad40cd 100644
--- a/components/script/dom/htmlobjectelement.rs
+++ b/components/script/dom/htmlobjectelement.rs
@@ -89,7 +89,7 @@ impl<'a> ProcessDataURL for &'a HTMLObjectElement {
     }
 }
 
-impl HTMLObjectElementMethods for HTMLObjectElement {
+impl HTMLObjectElementMethods<crate::DomTypeHolder> for HTMLObjectElement {
     // https://html.spec.whatwg.org/multipage/#dom-object-type
     make_getter!(Type, "type");
 
diff --git a/components/script/dom/htmloptgroupelement.rs b/components/script/dom/htmloptgroupelement.rs
index d0dbd725f4c3c..ef5adb06f2faf 100644
--- a/components/script/dom/htmloptgroupelement.rs
+++ b/components/script/dom/htmloptgroupelement.rs
@@ -75,7 +75,7 @@ impl HTMLOptGroupElement {
     }
 }
 
-impl HTMLOptGroupElementMethods for HTMLOptGroupElement {
+impl HTMLOptGroupElementMethods<crate::DomTypeHolder> for HTMLOptGroupElement {
     // https://html.spec.whatwg.org/multipage/#dom-optgroup-disabled
     make_bool_getter!(Disabled, "disabled");
 
diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs
index 649d35a50d810..66925d566729a 100644
--- a/components/script/dom/htmloptionelement.rs
+++ b/components/script/dom/htmloptionelement.rs
@@ -174,7 +174,7 @@ fn collect_text(element: &Element, value: &mut String) {
     }
 }
 
-impl HTMLOptionElementMethods for HTMLOptionElement {
+impl HTMLOptionElementMethods<crate::DomTypeHolder> for HTMLOptionElement {
     // https://html.spec.whatwg.org/multipage/#dom-option
     fn Option(
         window: &Window,
diff --git a/components/script/dom/htmloptionscollection.rs b/components/script/dom/htmloptionscollection.rs
index 6c6cb0b883371..ee36ff158b332 100644
--- a/components/script/dom/htmloptionscollection.rs
+++ b/components/script/dom/htmloptionscollection.rs
@@ -68,7 +68,7 @@ impl HTMLOptionsCollection {
     }
 }
 
-impl HTMLOptionsCollectionMethods for HTMLOptionsCollection {
+impl HTMLOptionsCollectionMethods<crate::DomTypeHolder> for HTMLOptionsCollection {
     // FIXME: This shouldn't need to be implemented here since HTMLCollection (the parent of
     // HTMLOptionsCollection) implements NamedGetter.
     // https://github.com/servo/servo/issues/5875
diff --git a/components/script/dom/htmloutputelement.rs b/components/script/dom/htmloutputelement.rs
index a83f28277a120..a3e4def8cc9e8 100644
--- a/components/script/dom/htmloutputelement.rs
+++ b/components/script/dom/htmloutputelement.rs
@@ -71,7 +71,7 @@ impl HTMLOutputElement {
     }
 }
 
-impl HTMLOutputElementMethods for HTMLOutputElement {
+impl HTMLOutputElementMethods<crate::DomTypeHolder> for HTMLOutputElement {
     // https://html.spec.whatwg.org/multipage/#dom-fae-form
     fn GetForm(&self) -> Option<DomRoot<HTMLFormElement>> {
         self.form_owner()
diff --git a/components/script/dom/htmlpreelement.rs b/components/script/dom/htmlpreelement.rs
index 54651c9633ef2..fcd152be7e53a 100644
--- a/components/script/dom/htmlpreelement.rs
+++ b/components/script/dom/htmlpreelement.rs
@@ -66,7 +66,7 @@ impl VirtualMethods for HTMLPreElement {
     }
 }
 
-impl HTMLPreElementMethods for HTMLPreElement {
+impl HTMLPreElementMethods<crate::DomTypeHolder> for HTMLPreElement {
     // https://html.spec.whatwg.org/multipage/#dom-pre-width
     make_int_getter!(Width, "width", 0);
 
diff --git a/components/script/dom/htmlprogresselement.rs b/components/script/dom/htmlprogresselement.rs
index 8c04391b9df9c..5a0ee59aa6b68 100644
--- a/components/script/dom/htmlprogresselement.rs
+++ b/components/script/dom/htmlprogresselement.rs
@@ -55,7 +55,7 @@ impl HTMLProgressElement {
     }
 }
 
-impl HTMLProgressElementMethods for HTMLProgressElement {
+impl HTMLProgressElementMethods<crate::DomTypeHolder> for HTMLProgressElement {
     // https://html.spec.whatwg.org/multipage/#dom-lfe-labels
     make_labels_getter!(Labels, labels_node_list);
 
diff --git a/components/script/dom/htmlquoteelement.rs b/components/script/dom/htmlquoteelement.rs
index 1caf6a1b46dc7..53ea04925d52b 100644
--- a/components/script/dom/htmlquoteelement.rs
+++ b/components/script/dom/htmlquoteelement.rs
@@ -49,7 +49,7 @@ impl HTMLQuoteElement {
     }
 }
 
-impl HTMLQuoteElementMethods for HTMLQuoteElement {
+impl HTMLQuoteElementMethods<crate::DomTypeHolder> for HTMLQuoteElement {
     // https://html.spec.whatwg.org/multipage/#dom-quote-cite
     make_url_getter!(Cite, "cite");
 
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index 86a803648a533..4ab12c60df101 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -1229,7 +1229,7 @@ impl VirtualMethods for HTMLScriptElement {
     }
 }
 
-impl HTMLScriptElementMethods for HTMLScriptElement {
+impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
     // https://html.spec.whatwg.org/multipage/#dom-script-src
     make_url_getter!(Src, "src");
 
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs
index f8abd9188cc03..ad0784b7b45ee 100644
--- a/components/script/dom/htmlselectelement.rs
+++ b/components/script/dom/htmlselectelement.rs
@@ -219,7 +219,7 @@ impl HTMLSelectElement {
     }
 }
 
-impl HTMLSelectElementMethods for HTMLSelectElement {
+impl HTMLSelectElementMethods<crate::DomTypeHolder> for HTMLSelectElement {
     // https://html.spec.whatwg.org/multipage/#dom-select-add
     fn Add(
         &self,
diff --git a/components/script/dom/htmlsourceelement.rs b/components/script/dom/htmlsourceelement.rs
index 80855156df446..886a935b0eabf 100644
--- a/components/script/dom/htmlsourceelement.rs
+++ b/components/script/dom/htmlsourceelement.rs
@@ -115,7 +115,7 @@ impl VirtualMethods for HTMLSourceElement {
     }
 }
 
-impl HTMLSourceElementMethods for HTMLSourceElement {
+impl HTMLSourceElementMethods<crate::DomTypeHolder> for HTMLSourceElement {
     // https://html.spec.whatwg.org/multipage/#dom-source-src
     make_getter!(Src, "src");
 
diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs
index 5f93eba9044af..3c228f4558611 100644
--- a/components/script/dom/htmlstyleelement.rs
+++ b/components/script/dom/htmlstyleelement.rs
@@ -277,7 +277,7 @@ impl StylesheetOwner for HTMLStyleElement {
     }
 }
 
-impl HTMLStyleElementMethods for HTMLStyleElement {
+impl HTMLStyleElementMethods<crate::DomTypeHolder> for HTMLStyleElement {
     /// <https://drafts.csswg.org/cssom/#dom-linkstyle-sheet>
     fn GetSheet(&self) -> Option<DomRoot<DOMStyleSheet>> {
         self.get_cssom_stylesheet().map(DomRoot::upcast)
diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs
index 50f4b20cb3834..4a5b125f3ea5f 100644
--- a/components/script/dom/htmltablecellelement.rs
+++ b/components/script/dom/htmltablecellelement.rs
@@ -65,7 +65,7 @@ impl HTMLTableCellElement {
     }
 }
 
-impl HTMLTableCellElementMethods for HTMLTableCellElement {
+impl HTMLTableCellElementMethods<crate::DomTypeHolder> for HTMLTableCellElement {
     // https://html.spec.whatwg.org/multipage/#dom-tdth-colspan
     make_uint_getter!(ColSpan, "colspan", DEFAULT_COLSPAN);
 
diff --git a/components/script/dom/htmltablecolelement.rs b/components/script/dom/htmltablecolelement.rs
index 522b6eaf93451..bdcd083d29648 100644
--- a/components/script/dom/htmltablecolelement.rs
+++ b/components/script/dom/htmltablecolelement.rs
@@ -60,7 +60,7 @@ impl HTMLTableColElement {
     }
 }
 
-impl HTMLTableColElementMethods for HTMLTableColElement {
+impl HTMLTableColElementMethods<crate::DomTypeHolder> for HTMLTableColElement {
     // <https://html.spec.whatwg.org/multipage/#attr-col-span>
     make_uint_getter!(Span, "span", DEFAULT_SPAN);
     // <https://html.spec.whatwg.org/multipage/#attr-col-span>
diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs
index 1d17116a6d52f..b4b3fceed9d06 100644
--- a/components/script/dom/htmltableelement.rs
+++ b/components/script/dom/htmltableelement.rs
@@ -188,7 +188,7 @@ impl HTMLTableElement {
     }
 }
 
-impl HTMLTableElementMethods for HTMLTableElement {
+impl HTMLTableElementMethods<crate::DomTypeHolder> for HTMLTableElement {
     // https://html.spec.whatwg.org/multipage/#dom-table-rows
     fn Rows(&self) -> DomRoot<HTMLCollection> {
         let filter = self.get_rows();
diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs
index 101182cff5721..790dce4dd7306 100644
--- a/components/script/dom/htmltablerowelement.rs
+++ b/components/script/dom/htmltablerowelement.rs
@@ -85,7 +85,7 @@ impl HTMLTableRowElement {
     }
 }
 
-impl HTMLTableRowElementMethods for HTMLTableRowElement {
+impl HTMLTableRowElementMethods<crate::DomTypeHolder> for HTMLTableRowElement {
     // https://html.spec.whatwg.org/multipage/#dom-tr-bgcolor
     make_getter!(BgColor, "bgcolor");
 
diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs
index 37669bfa8a65b..de6803ead41c7 100644
--- a/components/script/dom/htmltablesectionelement.rs
+++ b/components/script/dom/htmltablesectionelement.rs
@@ -70,7 +70,7 @@ impl CollectionFilter for RowsFilter {
     }
 }
 
-impl HTMLTableSectionElementMethods for HTMLTableSectionElement {
+impl HTMLTableSectionElementMethods<crate::DomTypeHolder> for HTMLTableSectionElement {
     // https://html.spec.whatwg.org/multipage/#dom-tbody-rows
     fn Rows(&self) -> DomRoot<HTMLCollection> {
         HTMLCollection::create(&window_from_node(self), self.upcast(), Box::new(RowsFilter))
diff --git a/components/script/dom/htmltemplateelement.rs b/components/script/dom/htmltemplateelement.rs
index 4e3432070fdef..ce83c8b2efe62 100644
--- a/components/script/dom/htmltemplateelement.rs
+++ b/components/script/dom/htmltemplateelement.rs
@@ -60,7 +60,7 @@ impl HTMLTemplateElement {
     }
 }
 
-impl HTMLTemplateElementMethods for HTMLTemplateElement {
+impl HTMLTemplateElementMethods<crate::DomTypeHolder> for HTMLTemplateElement {
     /// <https://html.spec.whatwg.org/multipage/#dom-template-content>
     fn Content(&self, can_gc: CanGc) -> DomRoot<DocumentFragment> {
         self.contents.or_init(|| {
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index 49e0cd204d5f1..cfdca55e52769 100644
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -222,7 +222,7 @@ impl TextControlElement for HTMLTextAreaElement {
     }
 }
 
-impl HTMLTextAreaElementMethods for HTMLTextAreaElement {
+impl HTMLTextAreaElementMethods<crate::DomTypeHolder> for HTMLTextAreaElement {
     // TODO A few of these attributes have default values and additional
     // constraints
 
diff --git a/components/script/dom/htmltimeelement.rs b/components/script/dom/htmltimeelement.rs
index 7b3046338aa8e..c54527548b41d 100644
--- a/components/script/dom/htmltimeelement.rs
+++ b/components/script/dom/htmltimeelement.rs
@@ -47,7 +47,7 @@ impl HTMLTimeElement {
     }
 }
 
-impl HTMLTimeElementMethods for HTMLTimeElement {
+impl HTMLTimeElementMethods<crate::DomTypeHolder> for HTMLTimeElement {
     // https://html.spec.whatwg.org/multipage/#dom-time-datetime
     make_getter!(DateTime, "datetime");
 
diff --git a/components/script/dom/htmltitleelement.rs b/components/script/dom/htmltitleelement.rs
index e67720efe83a9..29efcad052c17 100644
--- a/components/script/dom/htmltitleelement.rs
+++ b/components/script/dom/htmltitleelement.rs
@@ -63,7 +63,7 @@ impl HTMLTitleElement {
     }
 }
 
-impl HTMLTitleElementMethods for HTMLTitleElement {
+impl HTMLTitleElementMethods<crate::DomTypeHolder> for HTMLTitleElement {
     // https://html.spec.whatwg.org/multipage/#dom-title-text
     fn Text(&self) -> DOMString {
         self.upcast::<Node>().child_text_content()
diff --git a/components/script/dom/htmltrackelement.rs b/components/script/dom/htmltrackelement.rs
index 7f0889a01e547..f530753858fac 100644
--- a/components/script/dom/htmltrackelement.rs
+++ b/components/script/dom/htmltrackelement.rs
@@ -77,7 +77,7 @@ impl HTMLTrackElement {
     }
 }
 
-impl HTMLTrackElementMethods for HTMLTrackElement {
+impl HTMLTrackElementMethods<crate::DomTypeHolder> for HTMLTrackElement {
     // https://html.spec.whatwg.org/multipage/#dom-track-kind
     fn Kind(&self) -> DOMString {
         let element = self.upcast::<Element>();
diff --git a/components/script/dom/htmlulistelement.rs b/components/script/dom/htmlulistelement.rs
index a90fa85efb891..e462d66963e95 100644
--- a/components/script/dom/htmlulistelement.rs
+++ b/components/script/dom/htmlulistelement.rs
@@ -49,7 +49,7 @@ impl HTMLUListElement {
     }
 }
 
-impl HTMLUListElementMethods for HTMLUListElement {
+impl HTMLUListElementMethods<crate::DomTypeHolder> for HTMLUListElement {
     // https://html.spec.whatwg.org/multipage/#dom-ul-compact
     make_bool_getter!(Compact, "compact");
 
diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs
index 58981651a0e6c..77a00c1d48110 100644
--- a/components/script/dom/htmlvideoelement.rs
+++ b/components/script/dom/htmlvideoelement.rs
@@ -240,7 +240,7 @@ impl HTMLVideoElement {
     }
 }
 
-impl HTMLVideoElementMethods for HTMLVideoElement {
+impl HTMLVideoElementMethods<crate::DomTypeHolder> for HTMLVideoElement {
     // https://html.spec.whatwg.org/multipage/#dom-video-videowidth
     fn VideoWidth(&self) -> u32 {
         if self.htmlmediaelement.get_ready_state() == ReadyState::HaveNothing {
diff --git a/components/script/dom/iirfilternode.rs b/components/script/dom/iirfilternode.rs
index 7870c07995b8f..8e6d4fd8d11c3 100644
--- a/components/script/dom/iirfilternode.rs
+++ b/components/script/dom/iirfilternode.rs
@@ -95,7 +95,7 @@ impl IIRFilterNode {
     }
 }
 
-impl IIRFilterNodeMethods for IIRFilterNode {
+impl IIRFilterNodeMethods<crate::DomTypeHolder> for IIRFilterNode {
     /// <https://webaudio.github.io/web-audio-api/#dom-iirfilternode-iirfilternode>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/imagebitmap.rs b/components/script/dom/imagebitmap.rs
index 66294cbf05c6c..9215b889c0449 100644
--- a/components/script/dom/imagebitmap.rs
+++ b/components/script/dom/imagebitmap.rs
@@ -61,7 +61,7 @@ impl ImageBitmap {
     }
 }
 
-impl ImageBitmapMethods for ImageBitmap {
+impl ImageBitmapMethods<crate::DomTypeHolder> for ImageBitmap {
     /// <https://html.spec.whatwg.org/multipage/#dom-imagebitmap-height>
     fn Height(&self) -> u32 {
         // Step 1. If this's [[Detached]] internal slot's value is true, then return 0.
diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs
index 22b67650072fc..4fff85d8b9157 100644
--- a/components/script/dom/imagedata.rs
+++ b/components/script/dom/imagedata.rs
@@ -172,7 +172,7 @@ impl ImageData {
     }
 }
 
-impl ImageDataMethods for ImageData {
+impl ImageDataMethods<crate::DomTypeHolder> for ImageData {
     /// <https://html.spec.whatwg.org/multipage/#pixel-manipulation:dom-imagedata-3>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/inputevent.rs b/components/script/dom/inputevent.rs
index 5d658fe4eb651..1ba7a593b5c15 100644
--- a/components/script/dom/inputevent.rs
+++ b/components/script/dom/inputevent.rs
@@ -52,7 +52,7 @@ impl InputEvent {
     }
 }
 
-impl InputEventMethods for InputEvent {
+impl InputEventMethods<crate::DomTypeHolder> for InputEvent {
     // https://w3c.github.io/uievents/#dom-inputevent-inputevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/intersectionobserver.rs b/components/script/dom/intersectionobserver.rs
index 7b926e4909a9e..e6d2033e808b9 100644
--- a/components/script/dom/intersectionobserver.rs
+++ b/components/script/dom/intersectionobserver.rs
@@ -59,7 +59,7 @@ impl IntersectionObserver {
     }
 }
 
-impl IntersectionObserverMethods for IntersectionObserver {
+impl IntersectionObserverMethods<crate::DomTypeHolder> for IntersectionObserver {
     /// > The root provided to the IntersectionObserver constructor, or null if none was provided.
     ///
     /// <https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-root>
diff --git a/components/script/dom/intersectionobserverentry.rs b/components/script/dom/intersectionobserverentry.rs
index 08048c779fd55..f612902a2befa 100644
--- a/components/script/dom/intersectionobserverentry.rs
+++ b/components/script/dom/intersectionobserverentry.rs
@@ -44,7 +44,7 @@ impl IntersectionObserverEntry {
     }
 }
 
-impl IntersectionObserverEntryMethods for IntersectionObserverEntry {
+impl IntersectionObserverEntryMethods<crate::DomTypeHolder> for IntersectionObserverEntry {
     /// > The attribute must return a DOMHighResTimeStamp that corresponds to the time the
     /// > intersection was recorded, relative to the time origin of the global object
     /// > associated with the IntersectionObserver instance that generated the notification.
diff --git a/components/script/dom/keyboardevent.rs b/components/script/dom/keyboardevent.rs
index f8454a549059c..586fa715b6a32 100644
--- a/components/script/dom/keyboardevent.rs
+++ b/components/script/dom/keyboardevent.rs
@@ -158,7 +158,7 @@ impl KeyboardEvent {
     }
 }
 
-impl KeyboardEventMethods for KeyboardEvent {
+impl KeyboardEventMethods<crate::DomTypeHolder> for KeyboardEvent {
     /// <https://w3c.github.io/uievents/#dom-keyboardevent-keyboardevent>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs
index d8a2e1081ee85..d83e8549bfee4 100644
--- a/components/script/dom/location.rs
+++ b/components/script/dom/location.rs
@@ -262,7 +262,7 @@ impl Location {
     }
 }
 
-impl LocationMethods for Location {
+impl LocationMethods<crate::DomTypeHolder> for Location {
     // https://html.spec.whatwg.org/multipage/#dom-location-assign
     fn Assign(&self, url: USVString, can_gc: CanGc) -> ErrorResult {
         self.setter_common(
diff --git a/components/script/dom/mediadeviceinfo.rs b/components/script/dom/mediadeviceinfo.rs
index cfacd7c6271c9..3f45f06c95f24 100644
--- a/components/script/dom/mediadeviceinfo.rs
+++ b/components/script/dom/mediadeviceinfo.rs
@@ -54,7 +54,7 @@ impl MediaDeviceInfo {
     }
 }
 
-impl MediaDeviceInfoMethods for MediaDeviceInfo {
+impl MediaDeviceInfoMethods<crate::DomTypeHolder> for MediaDeviceInfo {
     /// <https://w3c.github.io/mediacapture-main/#dom-mediadeviceinfo-deviceid>
     fn DeviceId(&self) -> DOMString {
         self.device_id.clone()
diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs
index 985f0ee9409f9..8c2283e342591 100644
--- a/components/script/dom/mediadevices.rs
+++ b/components/script/dom/mediadevices.rs
@@ -44,7 +44,7 @@ impl MediaDevices {
     }
 }
 
-impl MediaDevicesMethods for MediaDevices {
+impl MediaDevicesMethods<crate::DomTypeHolder> for MediaDevices {
     /// <https://w3c.github.io/mediacapture-main/#dom-mediadevices-getusermedia>
     #[allow(unsafe_code)]
     fn GetUserMedia(
diff --git a/components/script/dom/mediaelementaudiosourcenode.rs b/components/script/dom/mediaelementaudiosourcenode.rs
index 007846bec2998..f0d1de62a0fd6 100644
--- a/components/script/dom/mediaelementaudiosourcenode.rs
+++ b/components/script/dom/mediaelementaudiosourcenode.rs
@@ -81,7 +81,7 @@ impl MediaElementAudioSourceNode {
     }
 }
 
-impl MediaElementAudioSourceNodeMethods for MediaElementAudioSourceNode {
+impl MediaElementAudioSourceNodeMethods<crate::DomTypeHolder> for MediaElementAudioSourceNode {
     /// <https://webaudio.github.io/web-audio-api/#dom-mediaelementaudiosourcenode-mediaelementaudiosourcenode>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/mediaerror.rs b/components/script/dom/mediaerror.rs
index 5fe5811a5aef7..e527d5e1456bb 100644
--- a/components/script/dom/mediaerror.rs
+++ b/components/script/dom/mediaerror.rs
@@ -29,7 +29,7 @@ impl MediaError {
     }
 }
 
-impl MediaErrorMethods for MediaError {
+impl MediaErrorMethods<crate::DomTypeHolder> for MediaError {
     // https://html.spec.whatwg.org/multipage/#dom-mediaerror-code
     fn Code(&self) -> u16 {
         self.code
diff --git a/components/script/dom/medialist.rs b/components/script/dom/medialist.rs
index 17f65bcba618a..faaba5307497a 100644
--- a/components/script/dom/medialist.rs
+++ b/components/script/dom/medialist.rs
@@ -58,7 +58,7 @@ impl MediaList {
     }
 }
 
-impl MediaListMethods for MediaList {
+impl MediaListMethods<crate::DomTypeHolder> for MediaList {
     /// <https://drafts.csswg.org/cssom/#dom-medialist-mediatext>
     fn MediaText(&self) -> DOMString {
         let guard = self.shared_lock().read();
diff --git a/components/script/dom/mediametadata.rs b/components/script/dom/mediametadata.rs
index fb642f08e32c5..083c6475ca317 100644
--- a/components/script/dom/mediametadata.rs
+++ b/components/script/dom/mediametadata.rs
@@ -64,7 +64,7 @@ impl MediaMetadata {
     }
 }
 
-impl MediaMetadataMethods for MediaMetadata {
+impl MediaMetadataMethods<crate::DomTypeHolder> for MediaMetadata {
     /// <https://w3c.github.io/mediasession/#dom-mediametadata-mediametadata>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/mediaquerylist.rs b/components/script/dom/mediaquerylist.rs
index ca675586578fe..41c9acabd64e3 100644
--- a/components/script/dom/mediaquerylist.rs
+++ b/components/script/dom/mediaquerylist.rs
@@ -78,7 +78,7 @@ impl MediaQueryList {
     }
 }
 
-impl MediaQueryListMethods for MediaQueryList {
+impl MediaQueryListMethods<crate::DomTypeHolder> for MediaQueryList {
     // https://drafts.csswg.org/cssom-view/#dom-mediaquerylist-media
     fn Media(&self) -> DOMString {
         self.media_query_list.to_css_string().into()
diff --git a/components/script/dom/mediaquerylistevent.rs b/components/script/dom/mediaquerylistevent.rs
index 6e141f2c10807..d810ea594d014 100644
--- a/components/script/dom/mediaquerylistevent.rs
+++ b/components/script/dom/mediaquerylistevent.rs
@@ -80,7 +80,7 @@ impl MediaQueryListEvent {
     }
 }
 
-impl MediaQueryListEventMethods for MediaQueryListEvent {
+impl MediaQueryListEventMethods<crate::DomTypeHolder> for MediaQueryListEvent {
     // https://drafts.csswg.org/cssom-view/#dom-mediaquerylistevent-mediaquerylistevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/mediasession.rs b/components/script/dom/mediasession.rs
index 760a71e57d002..bd4afd03d5ab6 100644
--- a/components/script/dom/mediasession.rs
+++ b/components/script/dom/mediasession.rs
@@ -124,7 +124,7 @@ impl MediaSession {
     }
 }
 
-impl MediaSessionMethods for MediaSession {
+impl MediaSessionMethods<crate::DomTypeHolder> for MediaSession {
     /// <https://w3c.github.io/mediasession/#dom-mediasession-metadata>
     fn GetMetadata(&self, can_gc: CanGc) -> Option<DomRoot<MediaMetadata>> {
         if let Some(ref metadata) = *self.metadata.borrow() {
diff --git a/components/script/dom/mediastream.rs b/components/script/dom/mediastream.rs
index 172bafe508c89..82ae137716af8 100644
--- a/components/script/dom/mediastream.rs
+++ b/components/script/dom/mediastream.rs
@@ -71,7 +71,7 @@ impl MediaStream {
     }
 }
 
-impl MediaStreamMethods for MediaStream {
+impl MediaStreamMethods<crate::DomTypeHolder> for MediaStream {
     /// <https://w3c.github.io/mediacapture-main/#dom-mediastream-constructor>
     fn Constructor(
         global: &Window,
diff --git a/components/script/dom/mediastreamaudiodestinationnode.rs b/components/script/dom/mediastreamaudiodestinationnode.rs
index 3c1004ab52c73..068ed36487062 100644
--- a/components/script/dom/mediastreamaudiodestinationnode.rs
+++ b/components/script/dom/mediastreamaudiodestinationnode.rs
@@ -83,7 +83,9 @@ impl MediaStreamAudioDestinationNode {
     }
 }
 
-impl MediaStreamAudioDestinationNodeMethods for MediaStreamAudioDestinationNode {
+impl MediaStreamAudioDestinationNodeMethods<crate::DomTypeHolder>
+    for MediaStreamAudioDestinationNode
+{
     /// <https://webaudio.github.io/web-audio-api/#dom-mediastreamaudiodestinationnode-mediastreamaudiodestinationnode>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/mediastreamaudiosourcenode.rs b/components/script/dom/mediastreamaudiosourcenode.rs
index 3bd92f87cfa12..59aa6625903f2 100644
--- a/components/script/dom/mediastreamaudiosourcenode.rs
+++ b/components/script/dom/mediastreamaudiosourcenode.rs
@@ -78,7 +78,7 @@ impl MediaStreamAudioSourceNode {
     }
 }
 
-impl MediaStreamAudioSourceNodeMethods for MediaStreamAudioSourceNode {
+impl MediaStreamAudioSourceNodeMethods<crate::DomTypeHolder> for MediaStreamAudioSourceNode {
     /// <https://webaudio.github.io/web-audio-api/#dom-mediastreamaudiosourcenode-mediastreamaudiosourcenode>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/mediastreamtrack.rs b/components/script/dom/mediastreamtrack.rs
index 4f1d7db683846..d0429e3ed5a46 100644
--- a/components/script/dom/mediastreamtrack.rs
+++ b/components/script/dom/mediastreamtrack.rs
@@ -50,7 +50,7 @@ impl MediaStreamTrack {
     }
 }
 
-impl MediaStreamTrackMethods for MediaStreamTrack {
+impl MediaStreamTrackMethods<crate::DomTypeHolder> for MediaStreamTrack {
     /// <https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-kind>
     fn Kind(&self) -> DOMString {
         match self.ty {
diff --git a/components/script/dom/mediastreamtrackaudiosourcenode.rs b/components/script/dom/mediastreamtrackaudiosourcenode.rs
index 2f4e30f46d653..39996f6ec1237 100644
--- a/components/script/dom/mediastreamtrackaudiosourcenode.rs
+++ b/components/script/dom/mediastreamtrackaudiosourcenode.rs
@@ -71,7 +71,9 @@ impl MediaStreamTrackAudioSourceNode {
     }
 }
 
-impl MediaStreamTrackAudioSourceNodeMethods for MediaStreamTrackAudioSourceNode {
+impl MediaStreamTrackAudioSourceNodeMethods<crate::DomTypeHolder>
+    for MediaStreamTrackAudioSourceNode
+{
     /// <https://webaudio.github.io/web-audio-api/#dom-mediastreamtrackaudiosourcenode-mediastreamtrackaudiosourcenode>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/messagechannel.rs b/components/script/dom/messagechannel.rs
index 8730e0bcea4ac..87149c951cbdf 100644
--- a/components/script/dom/messagechannel.rs
+++ b/components/script/dom/messagechannel.rs
@@ -56,7 +56,7 @@ impl MessageChannel {
     }
 }
 
-impl MessageChannelMethods for MessageChannel {
+impl MessageChannelMethods<crate::DomTypeHolder> for MessageChannel {
     /// <https://html.spec.whatwg.org/multipage/#dom-messagechannel>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs
index 7d2db88b4a17c..c868f1c5b9343 100644
--- a/components/script/dom/messageevent.rs
+++ b/components/script/dom/messageevent.rs
@@ -240,7 +240,7 @@ impl MessageEvent {
     }
 }
 
-impl MessageEventMethods for MessageEvent {
+impl MessageEventMethods<crate::DomTypeHolder> for MessageEvent {
     /// <https://html.spec.whatwg.org/multipage/#messageevent>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/messageport.rs b/components/script/dom/messageport.rs
index a915d92b50333..fc0ea06cadae0 100644
--- a/components/script/dom/messageport.rs
+++ b/components/script/dom/messageport.rs
@@ -269,7 +269,7 @@ impl Transferable for MessagePort {
     }
 }
 
-impl MessagePortMethods for MessagePort {
+impl MessagePortMethods<crate::DomTypeHolder> for MessagePort {
     /// <https://html.spec.whatwg.org/multipage/#dom-messageport-postmessage>
     fn PostMessage(
         &self,
diff --git a/components/script/dom/mimetype.rs b/components/script/dom/mimetype.rs
index 437f2bd4fe986..2c15982a9bfd8 100644
--- a/components/script/dom/mimetype.rs
+++ b/components/script/dom/mimetype.rs
@@ -15,7 +15,7 @@ pub struct MimeType {
     reflector_: Reflector,
 }
 
-impl MimeTypeMethods for MimeType {
+impl MimeTypeMethods<crate::DomTypeHolder> for MimeType {
     // https://html.spec.whatwg.org/multipage/#dom-mimetype-type
     fn Type(&self) -> DOMString {
         unreachable!()
diff --git a/components/script/dom/mimetypearray.rs b/components/script/dom/mimetypearray.rs
index 0495a8d187ea7..aa4a81438e800 100644
--- a/components/script/dom/mimetypearray.rs
+++ b/components/script/dom/mimetypearray.rs
@@ -28,7 +28,7 @@ impl MimeTypeArray {
     }
 }
 
-impl MimeTypeArrayMethods for MimeTypeArray {
+impl MimeTypeArrayMethods<crate::DomTypeHolder> for MimeTypeArray {
     // https://html.spec.whatwg.org/multipage/#dom-mimetypearray-length
     fn Length(&self) -> u32 {
         0
diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs
index ceea0f5c46e82..b551cca72d1d9 100644
--- a/components/script/dom/mouseevent.rs
+++ b/components/script/dom/mouseevent.rs
@@ -187,7 +187,7 @@ impl MouseEvent {
     }
 }
 
-impl MouseEventMethods for MouseEvent {
+impl MouseEventMethods<crate::DomTypeHolder> for MouseEvent {
     // https://w3c.github.io/uievents/#dom-mouseevent-mouseevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/mutationobserver.rs b/components/script/dom/mutationobserver.rs
index bb329588c3f39..51da85a78ddb3 100644
--- a/components/script/dom/mutationobserver.rs
+++ b/components/script/dom/mutationobserver.rs
@@ -247,7 +247,7 @@ impl MutationObserver {
     }
 }
 
-impl MutationObserverMethods for MutationObserver {
+impl MutationObserverMethods<crate::DomTypeHolder> for MutationObserver {
     /// <https://dom.spec.whatwg.org/#dom-mutationobserver-mutationobserver>
     fn Constructor(
         global: &Window,
diff --git a/components/script/dom/mutationrecord.rs b/components/script/dom/mutationrecord.rs
index 15680f338bfed..1b0673ed6d1da 100644
--- a/components/script/dom/mutationrecord.rs
+++ b/components/script/dom/mutationrecord.rs
@@ -123,7 +123,7 @@ impl MutationRecord {
     }
 }
 
-impl MutationRecordMethods for MutationRecord {
+impl MutationRecordMethods<crate::DomTypeHolder> for MutationRecord {
     // https://dom.spec.whatwg.org/#dom-mutationrecord-type
     fn Type(&self) -> DOMString {
         self.record_type.clone()
diff --git a/components/script/dom/namednodemap.rs b/components/script/dom/namednodemap.rs
index 823ad044b5c2e..f474fae79592c 100644
--- a/components/script/dom/namednodemap.rs
+++ b/components/script/dom/namednodemap.rs
@@ -35,7 +35,7 @@ impl NamedNodeMap {
     }
 }
 
-impl NamedNodeMapMethods for NamedNodeMap {
+impl NamedNodeMapMethods<crate::DomTypeHolder> for NamedNodeMap {
     // https://dom.spec.whatwg.org/#dom-namednodemap-length
     fn Length(&self) -> u32 {
         self.owner.attrs().len() as u32
diff --git a/components/script/dom/navigationpreloadmanager.rs b/components/script/dom/navigationpreloadmanager.rs
index b285e1a5681c1..54e01fe84e727 100644
--- a/components/script/dom/navigationpreloadmanager.rs
+++ b/components/script/dom/navigationpreloadmanager.rs
@@ -44,7 +44,7 @@ impl NavigationPreloadManager {
     }
 }
 
-impl NavigationPreloadManagerMethods for NavigationPreloadManager {
+impl NavigationPreloadManagerMethods<crate::DomTypeHolder> for NavigationPreloadManager {
     // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-enable
     fn Enable(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
         let promise = Promise::new_in_current_realm(comp, can_gc);
diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs
index 969f006dd768a..10b9732ddb659 100644
--- a/components/script/dom/navigator.rs
+++ b/components/script/dom/navigator.rs
@@ -136,7 +136,7 @@ impl Navigator {
     }
 }
 
-impl NavigatorMethods for Navigator {
+impl NavigatorMethods<crate::DomTypeHolder> for Navigator {
     // https://html.spec.whatwg.org/multipage/#dom-navigator-product
     fn Product(&self) -> DOMString {
         navigatorinfo::Product()
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 3267204fda43d..d35a7503c51dc 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -2450,7 +2450,7 @@ impl Node {
     }
 }
 
-impl NodeMethods for Node {
+impl NodeMethods<crate::DomTypeHolder> for Node {
     /// <https://dom.spec.whatwg.org/#dom-node-nodetype>
     fn NodeType(&self) -> u16 {
         match self.type_id() {
diff --git a/components/script/dom/nodeiterator.rs b/components/script/dom/nodeiterator.rs
index 46bac1a8055ac..f02343be5dfef 100644
--- a/components/script/dom/nodeiterator.rs
+++ b/components/script/dom/nodeiterator.rs
@@ -69,7 +69,7 @@ impl NodeIterator {
     }
 }
 
-impl NodeIteratorMethods for NodeIterator {
+impl NodeIteratorMethods<crate::DomTypeHolder> for NodeIterator {
     // https://dom.spec.whatwg.org/#dom-nodeiterator-root
     fn Root(&self) -> DomRoot<Node> {
         DomRoot::from_ref(&*self.root_node)
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index 78e89640f7f1a..de8927831018d 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -90,7 +90,7 @@ impl NodeList {
     }
 }
 
-impl NodeListMethods for NodeList {
+impl NodeListMethods<crate::DomTypeHolder> for NodeList {
     // https://dom.spec.whatwg.org/#dom-nodelist-length
     fn Length(&self) -> u32 {
         match self.list_type {
diff --git a/components/script/dom/offlineaudiocompletionevent.rs b/components/script/dom/offlineaudiocompletionevent.rs
index 9cdbcea66c63a..ab9144964dd4d 100644
--- a/components/script/dom/offlineaudiocompletionevent.rs
+++ b/components/script/dom/offlineaudiocompletionevent.rs
@@ -72,7 +72,7 @@ impl OfflineAudioCompletionEvent {
     }
 }
 
-impl OfflineAudioCompletionEventMethods for OfflineAudioCompletionEvent {
+impl OfflineAudioCompletionEventMethods<crate::DomTypeHolder> for OfflineAudioCompletionEvent {
     // https://webaudio.github.io/web-audio-api/#dom-offlineaudiocompletionevent-offlineaudiocompletionevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/offlineaudiocontext.rs b/components/script/dom/offlineaudiocontext.rs
index bd3f13f6dd88e..e6f991001f250 100644
--- a/components/script/dom/offlineaudiocontext.rs
+++ b/components/script/dom/offlineaudiocontext.rs
@@ -98,7 +98,7 @@ impl OfflineAudioContext {
     }
 }
 
-impl OfflineAudioContextMethods for OfflineAudioContext {
+impl OfflineAudioContextMethods<crate::DomTypeHolder> for OfflineAudioContext {
     // https://webaudio.github.io/web-audio-api/#dom-offlineaudiocontext-offlineaudiocontext
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs
index 2be33688afca7..a33aea573eb80 100644
--- a/components/script/dom/offscreencanvas.rs
+++ b/components/script/dom/offscreencanvas.rs
@@ -138,7 +138,7 @@ impl OffscreenCanvas {
     }
 }
 
-impl OffscreenCanvasMethods for OffscreenCanvas {
+impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas {
     // https://html.spec.whatwg.org/multipage/#dom-offscreencanvas
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/offscreencanvasrenderingcontext2d.rs b/components/script/dom/offscreencanvasrenderingcontext2d.rs
index 23ed19b33e9a4..7eea394842dc0 100644
--- a/components/script/dom/offscreencanvasrenderingcontext2d.rs
+++ b/components/script/dom/offscreencanvasrenderingcontext2d.rs
@@ -83,7 +83,9 @@ impl OffscreenCanvasRenderingContext2D {
     }
 }
 
-impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContext2D {
+impl OffscreenCanvasRenderingContext2DMethods<crate::DomTypeHolder>
+    for OffscreenCanvasRenderingContext2D
+{
     // https://html.spec.whatwg.org/multipage/offscreencontext2d-canvas
     fn Canvas(&self) -> DomRoot<OffscreenCanvas> {
         DomRoot::from_ref(&self.canvas)
diff --git a/components/script/dom/oscillatornode.rs b/components/script/dom/oscillatornode.rs
index 6ead040d87322..7807eea01ab21 100644
--- a/components/script/dom/oscillatornode.rs
+++ b/components/script/dom/oscillatornode.rs
@@ -114,7 +114,7 @@ impl OscillatorNode {
     }
 }
 
-impl OscillatorNodeMethods for OscillatorNode {
+impl OscillatorNodeMethods<crate::DomTypeHolder> for OscillatorNode {
     // https://webaudio.github.io/web-audio-api/#dom-oscillatornode-oscillatornode
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/pagetransitionevent.rs b/components/script/dom/pagetransitionevent.rs
index 99f364e67b3f4..4718f86afcaf0 100644
--- a/components/script/dom/pagetransitionevent.rs
+++ b/components/script/dom/pagetransitionevent.rs
@@ -78,7 +78,7 @@ impl PageTransitionEvent {
     }
 }
 
-impl PageTransitionEventMethods for PageTransitionEvent {
+impl PageTransitionEventMethods<crate::DomTypeHolder> for PageTransitionEvent {
     // https://html.spec.whatwg.org/multipage/#pagetransitionevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/paintrenderingcontext2d.rs b/components/script/dom/paintrenderingcontext2d.rs
index 95c005dff3074..26281eea11282 100644
--- a/components/script/dom/paintrenderingcontext2d.rs
+++ b/components/script/dom/paintrenderingcontext2d.rs
@@ -85,7 +85,7 @@ impl PaintRenderingContext2D {
     }
 }
 
-impl PaintRenderingContext2DMethods for PaintRenderingContext2D {
+impl PaintRenderingContext2DMethods<crate::DomTypeHolder> for PaintRenderingContext2D {
     // https://html.spec.whatwg.org/multipage/#dom-context-2d-save
     fn Save(&self) {
         self.context.Save()
diff --git a/components/script/dom/paintsize.rs b/components/script/dom/paintsize.rs
index 900cfd8c6aadd..b3a1348791eac 100644
--- a/components/script/dom/paintsize.rs
+++ b/components/script/dom/paintsize.rs
@@ -36,7 +36,7 @@ impl PaintSize {
     }
 }
 
-impl PaintSizeMethods for PaintSize {
+impl PaintSizeMethods<crate::DomTypeHolder> for PaintSize {
     /// <https://drafts.css-houdini.org/css-paint-api/#paintsize>
     fn Width(&self) -> Finite<f64> {
         self.width
diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs
index 4287b347a8389..993b79ad17c76 100644
--- a/components/script/dom/paintworkletglobalscope.rs
+++ b/components/script/dom/paintworkletglobalscope.rs
@@ -491,7 +491,7 @@ impl PaintDefinition {
     }
 }
 
-impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope {
+impl PaintWorkletGlobalScopeMethods<crate::DomTypeHolder> for PaintWorkletGlobalScope {
     #[allow(unsafe_code)]
     #[allow(crown::unrooted_must_root)]
     /// <https://drafts.css-houdini.org/css-paint-api/#dom-paintworkletglobalscope-registerpaint>
diff --git a/components/script/dom/pannernode.rs b/components/script/dom/pannernode.rs
index 7954f4c494065..c2d558a2e731d 100644
--- a/components/script/dom/pannernode.rs
+++ b/components/script/dom/pannernode.rs
@@ -207,7 +207,7 @@ impl PannerNode {
     }
 }
 
-impl PannerNodeMethods for PannerNode {
+impl PannerNodeMethods<crate::DomTypeHolder> for PannerNode {
     // https://webaudio.github.io/web-audio-api/#dom-pannernode-pannernode
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/performance.rs b/components/script/dom/performance.rs
index 5ad3d63b40f68..be440b0080df3 100644
--- a/components/script/dom/performance.rs
+++ b/components/script/dom/performance.rs
@@ -414,7 +414,7 @@ impl Performance {
     }
 }
 
-impl PerformanceMethods for Performance {
+impl PerformanceMethods<crate::DomTypeHolder> for Performance {
     // FIXME(avada): this should be deprecated in the future, but some sites still use it
     // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html#performance-timing-attribute
     fn Timing(&self) -> DomRoot<PerformanceNavigationTiming> {
diff --git a/components/script/dom/performanceentry.rs b/components/script/dom/performanceentry.rs
index 46f13d71515aa..30a6779c87656 100644
--- a/components/script/dom/performanceentry.rs
+++ b/components/script/dom/performanceentry.rs
@@ -73,7 +73,7 @@ impl PerformanceEntry {
     }
 }
 
-impl PerformanceEntryMethods for PerformanceEntry {
+impl PerformanceEntryMethods<crate::DomTypeHolder> for PerformanceEntry {
     // https://w3c.github.io/performance-timeline/#dom-performanceentry-name
     fn Name(&self) -> DOMString {
         self.name.clone()
diff --git a/components/script/dom/performancenavigation.rs b/components/script/dom/performancenavigation.rs
index b37fe87f3ddc0..ede953eb08174 100644
--- a/components/script/dom/performancenavigation.rs
+++ b/components/script/dom/performancenavigation.rs
@@ -29,7 +29,7 @@ impl PerformanceNavigation {
     }
 }
 
-impl PerformanceNavigationMethods for PerformanceNavigation {
+impl PerformanceNavigationMethods<crate::DomTypeHolder> for PerformanceNavigation {
     // https://w3c.github.io/navigation-timing/#dom-performancenavigation-type
     fn Type(&self) -> u16 {
         PerformanceNavigationConstants::TYPE_NAVIGATE
diff --git a/components/script/dom/performancenavigationtiming.rs b/components/script/dom/performancenavigationtiming.rs
index b4489fa812226..844c740a487ac 100644
--- a/components/script/dom/performancenavigationtiming.rs
+++ b/components/script/dom/performancenavigationtiming.rs
@@ -60,7 +60,7 @@ impl PerformanceNavigationTiming {
 }
 
 // https://w3c.github.io/navigation-timing/
-impl PerformanceNavigationTimingMethods for PerformanceNavigationTiming {
+impl PerformanceNavigationTimingMethods<crate::DomTypeHolder> for PerformanceNavigationTiming {
     // https://w3c.github.io/navigation-timing/#dom-performancenavigationtiming-unloadeventstart
     fn UnloadEventStart(&self) -> DOMHighResTimeStamp {
         self.upcast::<PerformanceResourceTiming>()
diff --git a/components/script/dom/performanceobserver.rs b/components/script/dom/performanceobserver.rs
index f6d83d496ddea..c65d1555c5b3e 100644
--- a/components/script/dom/performanceobserver.rs
+++ b/components/script/dom/performanceobserver.rs
@@ -118,7 +118,7 @@ impl PerformanceObserver {
     }
 }
 
-impl PerformanceObserverMethods for PerformanceObserver {
+impl PerformanceObserverMethods<crate::DomTypeHolder> for PerformanceObserver {
     // https://w3c.github.io/performance-timeline/#dom-performanceobserver-constructor
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/performanceobserverentrylist.rs b/components/script/dom/performanceobserverentrylist.rs
index 12a38d0515a70..0bea8bada558a 100644
--- a/components/script/dom/performanceobserverentrylist.rs
+++ b/components/script/dom/performanceobserverentrylist.rs
@@ -37,7 +37,7 @@ impl PerformanceObserverEntryList {
     }
 }
 
-impl PerformanceObserverEntryListMethods for PerformanceObserverEntryList {
+impl PerformanceObserverEntryListMethods<crate::DomTypeHolder> for PerformanceObserverEntryList {
     // https://w3c.github.io/performance-timeline/#dom-performanceobserver
     fn GetEntries(&self) -> Vec<DomRoot<PerformanceEntry>> {
         self.entries
diff --git a/components/script/dom/performanceresourcetiming.rs b/components/script/dom/performanceresourcetiming.rs
index ac7791f9fed20..de716b05ea220 100644
--- a/components/script/dom/performanceresourcetiming.rs
+++ b/components/script/dom/performanceresourcetiming.rs
@@ -185,7 +185,7 @@ impl PerformanceResourceTiming {
 }
 
 // https://w3c.github.io/resource-timing/
-impl PerformanceResourceTimingMethods for PerformanceResourceTiming {
+impl PerformanceResourceTimingMethods<crate::DomTypeHolder> for PerformanceResourceTiming {
     // https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-initiatortype
     fn InitiatorType(&self) -> DOMString {
         match self.initiator_type {
diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs
index ee1e19ec72c1c..94698261093e2 100644
--- a/components/script/dom/permissions.rs
+++ b/components/script/dom/permissions.rs
@@ -190,7 +190,7 @@ impl Permissions {
 }
 
 #[allow(non_snake_case)]
-impl PermissionsMethods for Permissions {
+impl PermissionsMethods<crate::DomTypeHolder> for Permissions {
     // https://w3c.github.io/permissions/#dom-permissions-query
     fn Query(&self, cx: JSContext, permissionDesc: *mut JSObject, can_gc: CanGc) -> Rc<Promise> {
         self.manipulate(Operation::Query, cx, permissionDesc, None, can_gc)
diff --git a/components/script/dom/permissionstatus.rs b/components/script/dom/permissionstatus.rs
index e210b5087fca9..c2262ca153ddb 100644
--- a/components/script/dom/permissionstatus.rs
+++ b/components/script/dom/permissionstatus.rs
@@ -48,7 +48,7 @@ impl PermissionStatus {
     }
 }
 
-impl PermissionStatusMethods for PermissionStatus {
+impl PermissionStatusMethods<crate::DomTypeHolder> for PermissionStatus {
     // https://w3c.github.io/permissions/#dom-permissionstatus-state
     fn State(&self) -> PermissionState {
         self.state.get()
diff --git a/components/script/dom/plugin.rs b/components/script/dom/plugin.rs
index 4b23191ff226b..8352acf3c95f4 100644
--- a/components/script/dom/plugin.rs
+++ b/components/script/dom/plugin.rs
@@ -15,7 +15,7 @@ pub struct Plugin {
     reflector_: Reflector,
 }
 
-impl PluginMethods for Plugin {
+impl PluginMethods<crate::DomTypeHolder> for Plugin {
     // https://html.spec.whatwg.org/multipage/#dom-plugin-name
     fn Name(&self) -> DOMString {
         unreachable!()
diff --git a/components/script/dom/pluginarray.rs b/components/script/dom/pluginarray.rs
index a0afeb1f10237..a1392ac43f75c 100644
--- a/components/script/dom/pluginarray.rs
+++ b/components/script/dom/pluginarray.rs
@@ -28,7 +28,7 @@ impl PluginArray {
     }
 }
 
-impl PluginArrayMethods for PluginArray {
+impl PluginArrayMethods<crate::DomTypeHolder> for PluginArray {
     // https://html.spec.whatwg.org/multipage/#dom-pluginarray-refresh
     fn Refresh(&self, _reload: bool) {}
 
diff --git a/components/script/dom/popstateevent.rs b/components/script/dom/popstateevent.rs
index d0a8afe2048a8..b7140a0661d12 100644
--- a/components/script/dom/popstateevent.rs
+++ b/components/script/dom/popstateevent.rs
@@ -81,7 +81,7 @@ impl PopStateEvent {
     }
 }
 
-impl PopStateEventMethods for PopStateEvent {
+impl PopStateEventMethods<crate::DomTypeHolder> for PopStateEvent {
     // https://html.spec.whatwg.org/multipage/#popstateevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/processinginstruction.rs b/components/script/dom/processinginstruction.rs
index 3d1232966085c..d09b1b9cd7da7 100644
--- a/components/script/dom/processinginstruction.rs
+++ b/components/script/dom/processinginstruction.rs
@@ -51,7 +51,7 @@ impl ProcessingInstruction {
     }
 }
 
-impl ProcessingInstructionMethods for ProcessingInstruction {
+impl ProcessingInstructionMethods<crate::DomTypeHolder> for ProcessingInstruction {
     // https://dom.spec.whatwg.org/#dom-processinginstruction-target
     fn Target(&self) -> DOMString {
         self.target.clone()
diff --git a/components/script/dom/progressevent.rs b/components/script/dom/progressevent.rs
index bbe0db66cffcb..e46e0a314a444 100644
--- a/components/script/dom/progressevent.rs
+++ b/components/script/dom/progressevent.rs
@@ -90,7 +90,7 @@ impl ProgressEvent {
     }
 }
 
-impl ProgressEventMethods for ProgressEvent {
+impl ProgressEventMethods<crate::DomTypeHolder> for ProgressEvent {
     // https://xhr.spec.whatwg.org/#dom-progressevent-progressevent
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/promiserejectionevent.rs b/components/script/dom/promiserejectionevent.rs
index 1a45790b7e1ed..30ca5ce5cf4b0 100644
--- a/components/script/dom/promiserejectionevent.rs
+++ b/components/script/dom/promiserejectionevent.rs
@@ -95,7 +95,7 @@ impl PromiseRejectionEvent {
     }
 }
 
-impl PromiseRejectionEventMethods for PromiseRejectionEvent {
+impl PromiseRejectionEventMethods<crate::DomTypeHolder> for PromiseRejectionEvent {
     // https://html.spec.whatwg.org/multipage/#promiserejectionevent
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/radionodelist.rs b/components/script/dom/radionodelist.rs
index d7c4aa8bb9e54..1614ab62c9805 100644
--- a/components/script/dom/radionodelist.rs
+++ b/components/script/dom/radionodelist.rs
@@ -63,7 +63,7 @@ impl RadioNodeList {
     }
 }
 
-impl RadioNodeListMethods for RadioNodeList {
+impl RadioNodeListMethods<crate::DomTypeHolder> for RadioNodeList {
     // https://dom.spec.whatwg.org/#dom-nodelist-length
     // https://github.com/servo/servo/issues/5875
     fn Length(&self) -> u32 {
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs
index 5801f1c702163..d6e4a403c1b3d 100644
--- a/components/script/dom/range.rs
+++ b/components/script/dom/range.rs
@@ -326,7 +326,7 @@ impl Range {
     }
 }
 
-impl RangeMethods for Range {
+impl RangeMethods<crate::DomTypeHolder> for Range {
     /// <https://dom.spec.whatwg.org/#dom-range>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs
index e205f3b3342ce..39d32c135cb89 100644
--- a/components/script/dom/request.rs
+++ b/components/script/dom/request.rs
@@ -156,7 +156,7 @@ fn request_is_locked(input: &Request) -> bool {
     input.is_locked()
 }
 
-impl RequestMethods for Request {
+impl RequestMethods<crate::DomTypeHolder> for Request {
     // https://fetch.spec.whatwg.org/#dom-request
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/resizeobserver.rs b/components/script/dom/resizeobserver.rs
index 31e111cb2ad2c..c548900282495 100644
--- a/components/script/dom/resizeobserver.rs
+++ b/components/script/dom/resizeobserver.rs
@@ -161,7 +161,7 @@ impl ResizeObserver {
     }
 }
 
-impl ResizeObserverMethods for ResizeObserver {
+impl ResizeObserverMethods<crate::DomTypeHolder> for ResizeObserver {
     /// <https://drafts.csswg.org/resize-observer/#dom-resizeobserver-resizeobserver>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/resizeobserverentry.rs b/components/script/dom/resizeobserverentry.rs
index a5017c4868c0b..3ffd53fad9925 100644
--- a/components/script/dom/resizeobserverentry.rs
+++ b/components/script/dom/resizeobserverentry.rs
@@ -78,7 +78,7 @@ impl ResizeObserverEntry {
     }
 }
 
-impl ResizeObserverEntryMethods for ResizeObserverEntry {
+impl ResizeObserverEntryMethods<crate::DomTypeHolder> for ResizeObserverEntry {
     /// <https://drafts.csswg.org/resize-observer/#dom-resizeobserverentry-target>
     fn Target(&self) -> DomRoot<Element> {
         DomRoot::from_ref(&*self.target)
diff --git a/components/script/dom/resizeobserversize.rs b/components/script/dom/resizeobserversize.rs
index 055472a3ca8ca..db5ef2a7e9631 100644
--- a/components/script/dom/resizeobserversize.rs
+++ b/components/script/dom/resizeobserversize.rs
@@ -59,7 +59,7 @@ impl ResizeObserverSize {
     }
 }
 
-impl ResizeObserverSizeMethods for ResizeObserverSize {
+impl ResizeObserverSizeMethods<crate::DomTypeHolder> for ResizeObserverSize {
     /// <https://drafts.csswg.org/resize-observer/#dom-resizeobserversize-inlinesize>
     fn InlineSize(&self) -> f64 {
         self.size_impl.inline_size()
diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs
index 258247fb2d95c..83c94e918747d 100644
--- a/components/script/dom/response.rs
+++ b/components/script/dom/response.rs
@@ -140,7 +140,7 @@ fn is_null_body_status(status: u16) -> bool {
     status == 101 || status == 204 || status == 205 || status == 304
 }
 
-impl ResponseMethods for Response {
+impl ResponseMethods<crate::DomTypeHolder> for Response {
     // https://fetch.spec.whatwg.org/#initialize-a-response
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs
index ab38b4615469c..0c5ca6e3abf5e 100644
--- a/components/script/dom/rtcdatachannel.rs
+++ b/components/script/dom/rtcdatachannel.rs
@@ -256,7 +256,7 @@ enum SendSource<'a, 'b> {
     ArrayBufferView(CustomAutoRooterGuard<'b, ArrayBufferView>),
 }
 
-impl RTCDataChannelMethods for RTCDataChannel {
+impl RTCDataChannelMethods<crate::DomTypeHolder> for RTCDataChannel {
     // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onopen
     event_handler!(open, GetOnopen, SetOnopen);
     // https://www.w3.org/TR/webrtc/#dom-rtcdatachannel-onbufferedamountlow
diff --git a/components/script/dom/rtcdatachannelevent.rs b/components/script/dom/rtcdatachannelevent.rs
index 55898897afc9e..dc35fc55621db 100644
--- a/components/script/dom/rtcdatachannelevent.rs
+++ b/components/script/dom/rtcdatachannelevent.rs
@@ -68,7 +68,7 @@ impl RTCDataChannelEvent {
     }
 }
 
-impl RTCDataChannelEventMethods for RTCDataChannelEvent {
+impl RTCDataChannelEventMethods<crate::DomTypeHolder> for RTCDataChannelEvent {
     // https://www.w3.org/TR/webrtc/#dom-rtcdatachannelevent-constructor
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/rtcerror.rs b/components/script/dom/rtcerror.rs
index 372a96f6989a7..c58a09d4d01d3 100644
--- a/components/script/dom/rtcerror.rs
+++ b/components/script/dom/rtcerror.rs
@@ -68,7 +68,7 @@ impl RTCError {
     }
 }
 
-impl RTCErrorMethods for RTCError {
+impl RTCErrorMethods<crate::DomTypeHolder> for RTCError {
     // https://www.w3.org/TR/webrtc/#dom-rtcerror-constructor
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/rtcerrorevent.rs b/components/script/dom/rtcerrorevent.rs
index 66d93b7fca96e..9dccf41402e42 100644
--- a/components/script/dom/rtcerrorevent.rs
+++ b/components/script/dom/rtcerrorevent.rs
@@ -68,7 +68,7 @@ impl RTCErrorEvent {
     }
 }
 
-impl RTCErrorEventMethods for RTCErrorEvent {
+impl RTCErrorEventMethods<crate::DomTypeHolder> for RTCErrorEvent {
     // https://www.w3.org/TR/webrtc/#dom-rtcerrorevent-constructor
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/rtcicecandidate.rs b/components/script/dom/rtcicecandidate.rs
index 3d3d60fdad3fc..1fec862fc603c 100644
--- a/components/script/dom/rtcicecandidate.rs
+++ b/components/script/dom/rtcicecandidate.rs
@@ -83,7 +83,7 @@ impl RTCIceCandidate {
     }
 }
 
-impl RTCIceCandidateMethods for RTCIceCandidate {
+impl RTCIceCandidateMethods<crate::DomTypeHolder> for RTCIceCandidate {
     /// <https://w3c.github.io/webrtc-pc/#dom-rtcicecandidate-constructor>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs
index 28e39837f3b35..60b4013527328 100644
--- a/components/script/dom/rtcpeerconnection.rs
+++ b/components/script/dom/rtcpeerconnection.rs
@@ -523,7 +523,7 @@ impl RTCPeerConnection {
     }
 }
 
-impl RTCPeerConnectionMethods for RTCPeerConnection {
+impl RTCPeerConnectionMethods<crate::DomTypeHolder> for RTCPeerConnection {
     // https://w3c.github.io/webrtc-pc/#dom-peerconnection
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/rtcpeerconnectioniceevent.rs b/components/script/dom/rtcpeerconnectioniceevent.rs
index a1f1aa6575b5e..e677b96b3f9a5 100644
--- a/components/script/dom/rtcpeerconnectioniceevent.rs
+++ b/components/script/dom/rtcpeerconnectioniceevent.rs
@@ -73,7 +73,7 @@ impl RTCPeerConnectionIceEvent {
     }
 }
 
-impl RTCPeerConnectionIceEventMethods for RTCPeerConnectionIceEvent {
+impl RTCPeerConnectionIceEventMethods<crate::DomTypeHolder> for RTCPeerConnectionIceEvent {
     /// <https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnectioniceevent-constructor>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/rtcrtpsender.rs b/components/script/dom/rtcrtpsender.rs
index 08dba4ed884ed..409254269c0ad 100644
--- a/components/script/dom/rtcrtpsender.rs
+++ b/components/script/dom/rtcrtpsender.rs
@@ -33,7 +33,7 @@ impl RTCRtpSender {
     }
 }
 
-impl RTCRtpSenderMethods for RTCRtpSender {
+impl RTCRtpSenderMethods<crate::DomTypeHolder> for RTCRtpSender {
     // https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-getparameters
     fn GetParameters(&self) -> RTCRtpSendParameters {
         RTCRtpSendParameters {
diff --git a/components/script/dom/rtcrtptransceiver.rs b/components/script/dom/rtcrtptransceiver.rs
index 6ac881fe56ad9..742bfc62390ad 100644
--- a/components/script/dom/rtcrtptransceiver.rs
+++ b/components/script/dom/rtcrtptransceiver.rs
@@ -39,7 +39,7 @@ impl RTCRtpTransceiver {
     }
 }
 
-impl RTCRtpTransceiverMethods for RTCRtpTransceiver {
+impl RTCRtpTransceiverMethods<crate::DomTypeHolder> for RTCRtpTransceiver {
     /// <https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction>
     fn Direction(&self) -> RTCRtpTransceiverDirection {
         self.direction.get()
diff --git a/components/script/dom/rtcsessiondescription.rs b/components/script/dom/rtcsessiondescription.rs
index 19a790c155bef..fae3d5f6b3bf7 100644
--- a/components/script/dom/rtcsessiondescription.rs
+++ b/components/script/dom/rtcsessiondescription.rs
@@ -48,7 +48,7 @@ impl RTCSessionDescription {
     }
 }
 
-impl RTCSessionDescriptionMethods for RTCSessionDescription {
+impl RTCSessionDescriptionMethods<crate::DomTypeHolder> for RTCSessionDescription {
     /// <https://w3c.github.io/webrtc-pc/#dom-sessiondescription>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/rtctrackevent.rs b/components/script/dom/rtctrackevent.rs
index 49626d2709571..03779eae79484 100644
--- a/components/script/dom/rtctrackevent.rs
+++ b/components/script/dom/rtctrackevent.rs
@@ -68,7 +68,7 @@ impl RTCTrackEvent {
     }
 }
 
-impl RTCTrackEventMethods for RTCTrackEvent {
+impl RTCTrackEventMethods<crate::DomTypeHolder> for RTCTrackEvent {
     // https://w3c.github.io/webrtc-pc/#dom-rtctrackevent-constructor
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/screen.rs b/components/script/dom/screen.rs
index f45f6355269f1..2b29744f6a68e 100644
--- a/components/script/dom/screen.rs
+++ b/components/script/dom/screen.rs
@@ -60,7 +60,7 @@ impl Screen {
     }
 }
 
-impl ScreenMethods for Screen {
+impl ScreenMethods<crate::DomTypeHolder> for Screen {
     // https://drafts.csswg.org/cssom-view/#dom-screen-availwidth
     fn AvailWidth(&self) -> Finite<f64> {
         Finite::wrap(self.screen_avail_size().width as f64)
diff --git a/components/script/dom/securitypolicyviolationevent.rs b/components/script/dom/securitypolicyviolationevent.rs
index f258e326955ad..31bb29af2d282 100644
--- a/components/script/dom/securitypolicyviolationevent.rs
+++ b/components/script/dom/securitypolicyviolationevent.rs
@@ -100,7 +100,7 @@ impl SecurityPolicyViolationEvent {
 }
 
 #[allow(non_snake_case)]
-impl SecurityPolicyViolationEventMethods for SecurityPolicyViolationEvent {
+impl SecurityPolicyViolationEventMethods<crate::DomTypeHolder> for SecurityPolicyViolationEvent {
     /// <https://w3c.github.io/webappsec-csp/#dom-securitypolicyviolationevent-securitypolicyviolationevent>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/selection.rs b/components/script/dom/selection.rs
index fbe5047a12e26..169f177318d59 100644
--- a/components/script/dom/selection.rs
+++ b/components/script/dom/selection.rs
@@ -109,7 +109,7 @@ impl Selection {
     }
 }
 
-impl SelectionMethods for Selection {
+impl SelectionMethods<crate::DomTypeHolder> for Selection {
     // https://w3c.github.io/selection-api/#dom-selection-anchornode
     fn GetAnchorNode(&self) -> Option<DomRoot<Node>> {
         if let Some(range) = self.range.get() {
diff --git a/components/script/dom/serviceworker.rs b/components/script/dom/serviceworker.rs
index e6ce996855931..264318cf39fa0 100644
--- a/components/script/dom/serviceworker.rs
+++ b/components/script/dom/serviceworker.rs
@@ -118,7 +118,7 @@ impl ServiceWorker {
     }
 }
 
-impl ServiceWorkerMethods for ServiceWorker {
+impl ServiceWorkerMethods<crate::DomTypeHolder> for ServiceWorker {
     // https://w3c.github.io/ServiceWorker/#service-worker-state-attribute
     fn State(&self) -> ServiceWorkerState {
         self.state.get()
diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs
index 35121fba3a809..7ea6ea12e1ae9 100644
--- a/components/script/dom/serviceworkercontainer.rs
+++ b/components/script/dom/serviceworkercontainer.rs
@@ -54,7 +54,7 @@ impl ServiceWorkerContainer {
     }
 }
 
-impl ServiceWorkerContainerMethods for ServiceWorkerContainer {
+impl ServiceWorkerContainerMethods<crate::DomTypeHolder> for ServiceWorkerContainer {
     // https://w3c.github.io/ServiceWorker/#service-worker-container-controller-attribute
     fn GetController(&self) -> Option<DomRoot<ServiceWorker>> {
         self.client.get_controller()
diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs
index 479c4d82fcd85..2c2598f6833e1 100644
--- a/components/script/dom/serviceworkerglobalscope.rs
+++ b/components/script/dom/serviceworkerglobalscope.rs
@@ -502,7 +502,7 @@ unsafe extern "C" fn interrupt_callback(cx: *mut JSContext) -> bool {
     !worker.is_closing()
 }
 
-impl ServiceWorkerGlobalScopeMethods for ServiceWorkerGlobalScope {
+impl ServiceWorkerGlobalScopeMethods<crate::DomTypeHolder> for ServiceWorkerGlobalScope {
     // https://w3c.github.io/ServiceWorker/#dom-serviceworkerglobalscope-onmessage
     event_handler!(message, GetOnmessage, SetOnmessage);
 
diff --git a/components/script/dom/serviceworkerregistration.rs b/components/script/dom/serviceworkerregistration.rs
index bd617942e07a7..59a4cb698bd5c 100644
--- a/components/script/dom/serviceworkerregistration.rs
+++ b/components/script/dom/serviceworkerregistration.rs
@@ -164,7 +164,7 @@ pub fn longest_prefix_match(stored_scope: &ServoUrl, potential_match: &ServoUrl)
         .all(|(scope, matched)| scope == matched)
 }
 
-impl ServiceWorkerRegistrationMethods for ServiceWorkerRegistration {
+impl ServiceWorkerRegistrationMethods<crate::DomTypeHolder> for ServiceWorkerRegistration {
     // https://w3c.github.io/ServiceWorker/#service-worker-registration-installing-attribute
     fn GetInstalling(&self) -> Option<DomRoot<ServiceWorker>> {
         self.installing
diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs
index 22967bb5ad256..3154e8f641a89 100644
--- a/components/script/dom/shadowroot.rs
+++ b/components/script/dom/shadowroot.rs
@@ -175,7 +175,7 @@ impl ShadowRoot {
     }
 }
 
-impl ShadowRootMethods for ShadowRoot {
+impl ShadowRootMethods<crate::DomTypeHolder> for ShadowRoot {
     // https://html.spec.whatwg.org/multipage/#dom-document-activeelement
     fn GetActiveElement(&self) -> Option<DomRoot<Element>> {
         self.document_or_shadow_root
diff --git a/components/script/dom/staticrange.rs b/components/script/dom/staticrange.rs
index 273beb16ad008..31c4e276338d5 100644
--- a/components/script/dom/staticrange.rs
+++ b/components/script/dom/staticrange.rs
@@ -6,7 +6,9 @@ use dom_struct::dom_struct;
 use js::rust::HandleObject;
 
 use crate::dom::abstractrange::AbstractRange;
-use crate::dom::bindings::codegen::Bindings::StaticRangeBinding::StaticRangeInit;
+use crate::dom::bindings::codegen::Bindings::StaticRangeBinding::{
+    StaticRangeInit, StaticRangeMethods,
+};
 use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
 use crate::dom::bindings::error::{Error, Fallible};
 use crate::dom::bindings::inheritance::NodeTypeId;
@@ -66,10 +68,12 @@ impl StaticRange {
         );
         staticrange
     }
+}
 
+impl StaticRangeMethods<crate::DomTypeHolder> for StaticRange {
     /// <https://dom.spec.whatwg.org/#dom-staticrange-staticrange>
     #[allow(non_snake_case)]
-    pub fn Constructor(
+    fn Constructor(
         window: &Window,
         proto: Option<HandleObject>,
         can_gc: CanGc,
diff --git a/components/script/dom/stereopannernode.rs b/components/script/dom/stereopannernode.rs
index 1e1b05a7b4321..6a7929b8735ef 100644
--- a/components/script/dom/stereopannernode.rs
+++ b/components/script/dom/stereopannernode.rs
@@ -101,7 +101,7 @@ impl StereoPannerNode {
     }
 }
 
-impl StereoPannerNodeMethods for StereoPannerNode {
+impl StereoPannerNodeMethods<crate::DomTypeHolder> for StereoPannerNode {
     // https://webaudio.github.io/web-audio-api/#dom-stereopannernode-stereopannernode
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs
index 030c095721731..4e230f554f77b 100644
--- a/components/script/dom/storage.rs
+++ b/components/script/dom/storage.rs
@@ -51,7 +51,7 @@ impl Storage {
     }
 }
 
-impl StorageMethods for Storage {
+impl StorageMethods<crate::DomTypeHolder> for Storage {
     // https://html.spec.whatwg.org/multipage/#dom-storage-length
     fn Length(&self) -> u32 {
         let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
diff --git a/components/script/dom/storageevent.rs b/components/script/dom/storageevent.rs
index 2fc491c54a83d..a99e8ce1a6dc1 100644
--- a/components/script/dom/storageevent.rs
+++ b/components/script/dom/storageevent.rs
@@ -134,7 +134,7 @@ impl StorageEvent {
 }
 
 #[allow(non_snake_case)]
-impl StorageEventMethods for StorageEvent {
+impl StorageEventMethods<crate::DomTypeHolder> for StorageEvent {
     // https://html.spec.whatwg.org/multipage/#storageevent
     fn Constructor(
         global: &Window,
diff --git a/components/script/dom/stylepropertymapreadonly.rs b/components/script/dom/stylepropertymapreadonly.rs
index 78aaeede4a38b..96eb481e90d7a 100644
--- a/components/script/dom/stylepropertymapreadonly.rs
+++ b/components/script/dom/stylepropertymapreadonly.rs
@@ -60,7 +60,7 @@ impl StylePropertyMapReadOnly {
     }
 }
 
-impl StylePropertyMapReadOnlyMethods for StylePropertyMapReadOnly {
+impl StylePropertyMapReadOnlyMethods<crate::DomTypeHolder> for StylePropertyMapReadOnly {
     /// <https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymapreadonly-get>
     fn Get(&self, property: DOMString) -> Option<DomRoot<CSSStyleValue>> {
         // TODO: avoid constructing an Atom
diff --git a/components/script/dom/stylesheet.rs b/components/script/dom/stylesheet.rs
index 3a35302c58e7f..bedb79c931dae 100644
--- a/components/script/dom/stylesheet.rs
+++ b/components/script/dom/stylesheet.rs
@@ -37,7 +37,7 @@ impl StyleSheet {
     }
 }
 
-impl StyleSheetMethods for StyleSheet {
+impl StyleSheetMethods<crate::DomTypeHolder> for StyleSheet {
     // https://drafts.csswg.org/cssom/#dom-stylesheet-type
     fn Type_(&self) -> DOMString {
         self.type_.clone()
diff --git a/components/script/dom/stylesheetlist.rs b/components/script/dom/stylesheetlist.rs
index f430b905584d7..87d5838bfeebb 100644
--- a/components/script/dom/stylesheetlist.rs
+++ b/components/script/dom/stylesheetlist.rs
@@ -87,7 +87,7 @@ impl StyleSheetList {
     }
 }
 
-impl StyleSheetListMethods for StyleSheetList {
+impl StyleSheetListMethods<crate::DomTypeHolder> for StyleSheetList {
     // https://drafts.csswg.org/cssom/#dom-stylesheetlist-length
     fn Length(&self) -> u32 {
         self.document_or_shadow_root.stylesheet_count() as u32
diff --git a/components/script/dom/submitevent.rs b/components/script/dom/submitevent.rs
index ea95805cbf565..6fb4e345b7245 100644
--- a/components/script/dom/submitevent.rs
+++ b/components/script/dom/submitevent.rs
@@ -68,7 +68,7 @@ impl SubmitEvent {
     }
 }
 
-impl SubmitEventMethods for SubmitEvent {
+impl SubmitEventMethods<crate::DomTypeHolder> for SubmitEvent {
     /// <https://html.spec.whatwg.org/multipage/#submitevent>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/subtlecrypto.rs b/components/script/dom/subtlecrypto.rs
index 583e3d0eb0130..fe37f7d724cbe 100644
--- a/components/script/dom/subtlecrypto.rs
+++ b/components/script/dom/subtlecrypto.rs
@@ -153,7 +153,7 @@ impl SubtleCrypto {
     }
 }
 
-impl SubtleCryptoMethods for SubtleCrypto {
+impl SubtleCryptoMethods<crate::DomTypeHolder> for SubtleCrypto {
     /// <https://w3c.github.io/webcrypto/#SubtleCrypto-method-encrypt>
     fn Encrypt(
         &self,
diff --git a/components/script/dom/svgelement.rs b/components/script/dom/svgelement.rs
index 9a9b79a2ad691..3c738b1f54e58 100644
--- a/components/script/dom/svgelement.rs
+++ b/components/script/dom/svgelement.rs
@@ -66,7 +66,7 @@ impl VirtualMethods for SVGElement {
     }
 }
 
-impl SVGElementMethods for SVGElement {
+impl SVGElementMethods<crate::DomTypeHolder> for SVGElement {
     // https://html.spec.whatwg.org/multipage/#the-style-attribute
     fn Style(&self) -> DomRoot<CSSStyleDeclaration> {
         self.style_decl.or_init(|| {
diff --git a/components/script/dom/text.rs b/components/script/dom/text.rs
index c9381f207a8ba..b2d3fab239669 100644
--- a/components/script/dom/text.rs
+++ b/components/script/dom/text.rs
@@ -52,7 +52,7 @@ impl Text {
     }
 }
 
-impl TextMethods for Text {
+impl TextMethods<crate::DomTypeHolder> for Text {
     // https://dom.spec.whatwg.org/#dom-text-text
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/textdecoder.rs b/components/script/dom/textdecoder.rs
index 3491503bb91fa..c1312631647b6 100644
--- a/components/script/dom/textdecoder.rs
+++ b/components/script/dom/textdecoder.rs
@@ -77,7 +77,7 @@ impl TextDecoder {
     }
 }
 
-impl TextDecoderMethods for TextDecoder {
+impl TextDecoderMethods<crate::DomTypeHolder> for TextDecoder {
     /// <https://encoding.spec.whatwg.org/#dom-textdecoder>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs
index 6a237abcfaf9b..55c5346029ca2 100644
--- a/components/script/dom/textencoder.rs
+++ b/components/script/dom/textencoder.rs
@@ -48,7 +48,7 @@ impl TextEncoder {
     }
 }
 
-impl TextEncoderMethods for TextEncoder {
+impl TextEncoderMethods<crate::DomTypeHolder> for TextEncoder {
     /// <https://encoding.spec.whatwg.org/#dom-textencoder>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/textmetrics.rs b/components/script/dom/textmetrics.rs
index 338edd023f2c8..6f7af09809ea0 100644
--- a/components/script/dom/textmetrics.rs
+++ b/components/script/dom/textmetrics.rs
@@ -98,7 +98,7 @@ impl TextMetrics {
     }
 }
 
-impl TextMetricsMethods for TextMetrics {
+impl TextMetricsMethods<crate::DomTypeHolder> for TextMetrics {
     /// <https://html.spec.whatwg.org/multipage/#dom-textmetrics-width>
     fn Width(&self) -> Finite<f64> {
         self.width
diff --git a/components/script/dom/texttrack.rs b/components/script/dom/texttrack.rs
index 390f538896281..a5d4686b7965f 100644
--- a/components/script/dom/texttrack.rs
+++ b/components/script/dom/texttrack.rs
@@ -88,7 +88,7 @@ impl TextTrack {
     }
 }
 
-impl TextTrackMethods for TextTrack {
+impl TextTrackMethods<crate::DomTypeHolder> for TextTrack {
     // https://html.spec.whatwg.org/multipage/#dom-texttrack-kind
     fn Kind(&self) -> TextTrackKind {
         self.kind
diff --git a/components/script/dom/texttrackcue.rs b/components/script/dom/texttrackcue.rs
index 5a0f7f3abeff8..f3c1d885a1ae9 100644
--- a/components/script/dom/texttrackcue.rs
+++ b/components/script/dom/texttrackcue.rs
@@ -66,7 +66,7 @@ impl TextTrackCue {
     }
 }
 
-impl TextTrackCueMethods for TextTrackCue {
+impl TextTrackCueMethods<crate::DomTypeHolder> for TextTrackCue {
     // https://html.spec.whatwg.org/multipage/#dom-texttrackcue-id
     fn Id(&self) -> DOMString {
         self.id()
diff --git a/components/script/dom/texttrackcuelist.rs b/components/script/dom/texttrackcuelist.rs
index 6c7e01e9c3871..69c2f836a599c 100644
--- a/components/script/dom/texttrackcuelist.rs
+++ b/components/script/dom/texttrackcuelist.rs
@@ -58,7 +58,7 @@ impl TextTrackCueList {
     }
 }
 
-impl TextTrackCueListMethods for TextTrackCueList {
+impl TextTrackCueListMethods<crate::DomTypeHolder> for TextTrackCueList {
     // https://html.spec.whatwg.org/multipage/#dom-texttrackcuelist-length
     fn Length(&self) -> u32 {
         self.dom_cues.borrow().len() as u32
diff --git a/components/script/dom/texttracklist.rs b/components/script/dom/texttracklist.rs
index 51aba9b0f0531..e5a3ad52c2cb9 100644
--- a/components/script/dom/texttracklist.rs
+++ b/components/script/dom/texttracklist.rs
@@ -109,7 +109,7 @@ impl TextTrackList {
     }
 }
 
-impl TextTrackListMethods for TextTrackList {
+impl TextTrackListMethods<crate::DomTypeHolder> for TextTrackList {
     // https://html.spec.whatwg.org/multipage/#dom-texttracklist-length
     fn Length(&self) -> u32 {
         self.dom_tracks.borrow().len() as u32
diff --git a/components/script/dom/timeranges.rs b/components/script/dom/timeranges.rs
index 496f7ee809025..c5fe744489d17 100644
--- a/components/script/dom/timeranges.rs
+++ b/components/script/dom/timeranges.rs
@@ -143,7 +143,7 @@ impl TimeRanges {
     }
 }
 
-impl TimeRangesMethods for TimeRanges {
+impl TimeRangesMethods<crate::DomTypeHolder> for TimeRanges {
     // https://html.spec.whatwg.org/multipage/#dom-timeranges-length
     fn Length(&self) -> u32 {
         self.ranges.len()
diff --git a/components/script/dom/touch.rs b/components/script/dom/touch.rs
index fcb1c1bee86e7..982f74a58bc4d 100644
--- a/components/script/dom/touch.rs
+++ b/components/script/dom/touch.rs
@@ -70,7 +70,7 @@ impl Touch {
     }
 }
 
-impl TouchMethods for Touch {
+impl TouchMethods<crate::DomTypeHolder> for Touch {
     /// <https://w3c.github.io/touch-events/#widl-Touch-identifier>
     fn Identifier(&self) -> i32 {
         self.identifier
diff --git a/components/script/dom/touchevent.rs b/components/script/dom/touchevent.rs
index 1bb29e8117803..7ef9e20b89976 100644
--- a/components/script/dom/touchevent.rs
+++ b/components/script/dom/touchevent.rs
@@ -95,7 +95,7 @@ impl TouchEvent {
     }
 }
 
-impl<'a> TouchEventMethods for &'a TouchEvent {
+impl TouchEventMethods<crate::DomTypeHolder> for TouchEvent {
     /// <https://w3c.github.io/touch-events/#widl-TouchEvent-ctrlKey>
     fn CtrlKey(&self) -> bool {
         self.ctrl_key.get()
diff --git a/components/script/dom/touchlist.rs b/components/script/dom/touchlist.rs
index ede60a456ce69..e139f23b2af7f 100644
--- a/components/script/dom/touchlist.rs
+++ b/components/script/dom/touchlist.rs
@@ -29,7 +29,7 @@ impl TouchList {
     }
 }
 
-impl TouchListMethods for TouchList {
+impl TouchListMethods<crate::DomTypeHolder> for TouchList {
     /// <https://w3c.github.io/touch-events/#widl-TouchList-length>
     fn Length(&self) -> u32 {
         self.touches.len() as u32
diff --git a/components/script/dom/trackevent.rs b/components/script/dom/trackevent.rs
index dfe9f2c030361..5a9c7b44578dd 100644
--- a/components/script/dom/trackevent.rs
+++ b/components/script/dom/trackevent.rs
@@ -93,7 +93,7 @@ impl TrackEvent {
     }
 }
 
-impl TrackEventMethods for TrackEvent {
+impl TrackEventMethods<crate::DomTypeHolder> for TrackEvent {
     // https://html.spec.whatwg.org/multipage/#trackevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/transitionevent.rs b/components/script/dom/transitionevent.rs
index 3e21a161934b3..66e7669ba693e 100644
--- a/components/script/dom/transitionevent.rs
+++ b/components/script/dom/transitionevent.rs
@@ -69,7 +69,7 @@ impl TransitionEvent {
     }
 }
 
-impl TransitionEventMethods for TransitionEvent {
+impl TransitionEventMethods<crate::DomTypeHolder> for TransitionEvent {
     // https://drafts.csswg.org/css-transitions/#dom-transitionevent-transitionevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs
index 97c5da54c502e..22631b65d38e0 100644
--- a/components/script/dom/treewalker.rs
+++ b/components/script/dom/treewalker.rs
@@ -67,7 +67,7 @@ impl TreeWalker {
     }
 }
 
-impl TreeWalkerMethods for TreeWalker {
+impl TreeWalkerMethods<crate::DomTypeHolder> for TreeWalker {
     // https://dom.spec.whatwg.org/#dom-treewalker-root
     fn Root(&self) -> DomRoot<Node> {
         DomRoot::from_ref(&*self.root_node)
diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs
index b9da779290874..a868f0e95885a 100644
--- a/components/script/dom/uievent.rs
+++ b/components/script/dom/uievent.rs
@@ -87,7 +87,7 @@ impl UIEvent {
     }
 }
 
-impl UIEventMethods for UIEvent {
+impl UIEventMethods<crate::DomTypeHolder> for UIEvent {
     /// <https://w3c.github.io/uievents/#dom-uievent-uievent>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs
index 0b5b798a51a8f..f9f87a9bba360 100644
--- a/components/script/dom/url.rs
+++ b/components/script/dom/url.rs
@@ -97,7 +97,7 @@ impl URL {
     }
 }
 
-impl URLMethods for URL {
+impl URLMethods<crate::DomTypeHolder> for URL {
     /// <https://url.spec.whatwg.org/#constructors>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/urlsearchparams.rs b/components/script/dom/urlsearchparams.rs
index e7bf92e52007b..b3712209f257f 100644
--- a/components/script/dom/urlsearchparams.rs
+++ b/components/script/dom/urlsearchparams.rs
@@ -61,7 +61,7 @@ impl URLSearchParams {
     }
 }
 
-impl URLSearchParamsMethods for URLSearchParams {
+impl URLSearchParamsMethods<crate::DomTypeHolder> for URLSearchParams {
     /// <https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs
index 8b2caa5526fb7..2e50da1a2543f 100755
--- a/components/script/dom/validitystate.rs
+++ b/components/script/dom/validitystate.rs
@@ -166,7 +166,7 @@ impl ValidityState {
     }
 }
 
-impl ValidityStateMethods for ValidityState {
+impl ValidityStateMethods<crate::DomTypeHolder> for ValidityState {
     // https://html.spec.whatwg.org/multipage/#dom-validitystate-valuemissing
     fn ValueMissing(&self) -> bool {
         self.invalid_flags()
diff --git a/components/script/dom/videotrack.rs b/components/script/dom/videotrack.rs
index 65003ed74df13..d417a246541fd 100644
--- a/components/script/dom/videotrack.rs
+++ b/components/script/dom/videotrack.rs
@@ -85,7 +85,7 @@ impl VideoTrack {
     }
 }
 
-impl VideoTrackMethods for VideoTrack {
+impl VideoTrackMethods<crate::DomTypeHolder> for VideoTrack {
     // https://html.spec.whatwg.org/multipage/#dom-videotrack-id
     fn Id(&self) -> DOMString {
         self.id()
diff --git a/components/script/dom/videotracklist.rs b/components/script/dom/videotracklist.rs
index 5c2f852dc7ded..465fc7a705f4f 100644
--- a/components/script/dom/videotracklist.rs
+++ b/components/script/dom/videotracklist.rs
@@ -125,7 +125,7 @@ impl VideoTrackList {
     }
 }
 
-impl VideoTrackListMethods for VideoTrackList {
+impl VideoTrackListMethods<crate::DomTypeHolder> for VideoTrackList {
     // https://html.spec.whatwg.org/multipage/#dom-videotracklist-length
     fn Length(&self) -> u32 {
         self.len() as u32
diff --git a/components/script/dom/visibilitystateentry.rs b/components/script/dom/visibilitystateentry.rs
index c08eac70b56c1..8d150a369dac6 100644
--- a/components/script/dom/visibilitystateentry.rs
+++ b/components/script/dom/visibilitystateentry.rs
@@ -55,7 +55,7 @@ impl VisibilityStateEntry {
     }
 }
 
-impl VisibilityStateEntryMethods for VisibilityStateEntry {
+impl VisibilityStateEntryMethods<crate::DomTypeHolder> for VisibilityStateEntry {
     /// <https://html.spec.whatwg.org/multipage/#visibilitystateentry-name>
     fn Name(&self) -> DOMString {
         self.entry.Name()
diff --git a/components/script/dom/vttcue.rs b/components/script/dom/vttcue.rs
index f97854dcc21e1..3c1b484ed09e2 100644
--- a/components/script/dom/vttcue.rs
+++ b/components/script/dom/vttcue.rs
@@ -78,7 +78,7 @@ impl VTTCue {
     }
 }
 
-impl VTTCueMethods for VTTCue {
+impl VTTCueMethods<crate::DomTypeHolder> for VTTCue {
     // https://w3c.github.io/webvtt/#dom-vttcue-vttcue
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/vttregion.rs b/components/script/dom/vttregion.rs
index 1280c3c9d8878..58a72f1354474 100644
--- a/components/script/dom/vttregion.rs
+++ b/components/script/dom/vttregion.rs
@@ -51,7 +51,7 @@ impl VTTRegion {
     }
 }
 
-impl VTTRegionMethods for VTTRegion {
+impl VTTRegionMethods<crate::DomTypeHolder> for VTTRegion {
     // https://w3c.github.io/webvtt/#dom-vttregion-vttregion
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs
index 0b6b1a22e44d8..80a73014ebc57 100644
--- a/components/script/dom/webgl2renderingcontext.rs
+++ b/components/script/dom/webgl2renderingcontext.rs
@@ -913,7 +913,7 @@ impl WebGL2RenderingContext {
     }
 }
 
-impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
+impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingContext {
     /// <https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1>
     fn Canvas(&self) -> HTMLCanvasElementOrOffscreenCanvas {
         self.base.Canvas()
diff --git a/components/script/dom/webgl_extensions/ext/angleinstancedarrays.rs b/components/script/dom/webgl_extensions/ext/angleinstancedarrays.rs
index 5c79a692adbf1..becfac572660c 100644
--- a/components/script/dom/webgl_extensions/ext/angleinstancedarrays.rs
+++ b/components/script/dom/webgl_extensions/ext/angleinstancedarrays.rs
@@ -62,7 +62,7 @@ impl WebGLExtension for ANGLEInstancedArrays {
     }
 }
 
-impl ANGLEInstancedArraysMethods for ANGLEInstancedArrays {
+impl ANGLEInstancedArraysMethods<crate::DomTypeHolder> for ANGLEInstancedArrays {
     // https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/
     fn DrawArraysInstancedANGLE(&self, mode: u32, first: i32, count: i32, primcount: i32) {
         handle_potential_webgl_error!(
diff --git a/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs b/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs
index 4ddb5c2fb52b6..7edabae4b73ef 100644
--- a/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs
+++ b/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs
@@ -29,7 +29,7 @@ impl OESVertexArrayObject {
     }
 }
 
-impl OESVertexArrayObjectMethods for OESVertexArrayObject {
+impl OESVertexArrayObjectMethods<crate::DomTypeHolder> for OESVertexArrayObject {
     // https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/
     fn CreateVertexArrayOES(&self) -> Option<DomRoot<WebGLVertexArrayObjectOES>> {
         self.ctx.create_vertex_array()
diff --git a/components/script/dom/webglactiveinfo.rs b/components/script/dom/webglactiveinfo.rs
index 80815357b8ec8..0a8a5b87f6865 100644
--- a/components/script/dom/webglactiveinfo.rs
+++ b/components/script/dom/webglactiveinfo.rs
@@ -38,7 +38,7 @@ impl WebGLActiveInfo {
     }
 }
 
-impl WebGLActiveInfoMethods for WebGLActiveInfo {
+impl WebGLActiveInfoMethods<crate::DomTypeHolder> for WebGLActiveInfo {
     // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.11.1
     fn Size(&self) -> i32 {
         self.size
diff --git a/components/script/dom/webglcontextevent.rs b/components/script/dom/webglcontextevent.rs
index 8a0c55ff58393..f8773c8222406 100644
--- a/components/script/dom/webglcontextevent.rs
+++ b/components/script/dom/webglcontextevent.rs
@@ -25,7 +25,7 @@ pub struct WebGLContextEvent {
     status_message: DOMString,
 }
 
-impl WebGLContextEventMethods for WebGLContextEvent {
+impl WebGLContextEventMethods<crate::DomTypeHolder> for WebGLContextEvent {
     // https://registry.khronos.org/webgl/specs/latest/1.0/#5.15
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/webglobject.rs b/components/script/dom/webglobject.rs
index 919bfc5cda71e..3eb03ce462027 100644
--- a/components/script/dom/webglobject.rs
+++ b/components/script/dom/webglobject.rs
@@ -33,7 +33,7 @@ impl WebGLObject {
     }
 }
 
-impl WebGLObjectMethods for WebGLObject {
+impl WebGLObjectMethods<crate::DomTypeHolder> for WebGLObject {
     /// <https://registry.khronos.org/webgl/specs/latest/1.0/#5.3>
     fn Label(&self) -> USVString {
         self.label.borrow().clone()
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 7751bce87ce46..215f076c22997 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -1994,7 +1994,7 @@ impl Drop for WebGLRenderingContext {
     }
 }
 
-impl WebGLRenderingContextMethods for WebGLRenderingContext {
+impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContext {
     // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
     fn Canvas(&self) -> HTMLCanvasElementOrOffscreenCanvas {
         self.canvas.clone()
diff --git a/components/script/dom/webglshaderprecisionformat.rs b/components/script/dom/webglshaderprecisionformat.rs
index b65a92b1939a5..d3abe48a8b9c8 100644
--- a/components/script/dom/webglshaderprecisionformat.rs
+++ b/components/script/dom/webglshaderprecisionformat.rs
@@ -45,7 +45,7 @@ impl WebGLShaderPrecisionFormat {
     }
 }
 
-impl WebGLShaderPrecisionFormatMethods for WebGLShaderPrecisionFormat {
+impl WebGLShaderPrecisionFormatMethods<crate::DomTypeHolder> for WebGLShaderPrecisionFormat {
     // https://www.khronos.org/registry/webgl/specs/1.0/#5.12.1
     fn RangeMin(&self) -> i32 {
         self.range_min
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index 745782c061d2b..6a97ec7a602e0 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -191,7 +191,7 @@ impl WebSocket {
     }
 }
 
-impl WebSocketMethods for WebSocket {
+impl WebSocketMethods<crate::DomTypeHolder> for WebSocket {
     /// <https://html.spec.whatwg.org/multipage/#dom-websocket>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/wheelevent.rs b/components/script/dom/wheelevent.rs
index 6b08723c33905..a81406d43a6fc 100644
--- a/components/script/dom/wheelevent.rs
+++ b/components/script/dom/wheelevent.rs
@@ -101,7 +101,7 @@ impl WheelEvent {
     }
 }
 
-impl WheelEventMethods for WheelEvent {
+impl WheelEventMethods<crate::DomTypeHolder> for WheelEvent {
     // https://w3c.github.io/uievents/#dom-wheelevent-wheelevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index d065e41e7e1bb..d7ac58667f077 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -625,7 +625,7 @@ pub fn base64_atob(input: DOMString) -> Fallible<DOMString> {
     Ok(data.iter().map(|&b| b as char).collect::<String>().into())
 }
 
-impl WindowMethods for Window {
+impl WindowMethods<crate::DomTypeHolder> for Window {
     // https://html.spec.whatwg.org/multipage/#dom-alert
     fn Alert_(&self) {
         self.Alert(DOMString::new());
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index 94a23496596f7..7a407635bca05 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -157,7 +157,7 @@ impl Worker {
     }
 }
 
-impl WorkerMethods for Worker {
+impl WorkerMethods<crate::DomTypeHolder> for Worker {
     // https://html.spec.whatwg.org/multipage/#dom-worker
     #[allow(unsafe_code)]
     fn Constructor(
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index f441f4265c60a..fc896810e9d01 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -242,7 +242,7 @@ impl WorkerGlobalScope {
     }
 }
 
-impl WorkerGlobalScopeMethods for WorkerGlobalScope {
+impl WorkerGlobalScopeMethods<crate::DomTypeHolder> for WorkerGlobalScope {
     // https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self
     fn Self_(&self) -> DomRoot<WorkerGlobalScope> {
         DomRoot::from_ref(self)
diff --git a/components/script/dom/workerlocation.rs b/components/script/dom/workerlocation.rs
index d69dcc804c1a1..84afb2699d868 100644
--- a/components/script/dom/workerlocation.rs
+++ b/components/script/dom/workerlocation.rs
@@ -39,7 +39,7 @@ impl WorkerLocation {
     }
 }
 
-impl WorkerLocationMethods for WorkerLocation {
+impl WorkerLocationMethods<crate::DomTypeHolder> for WorkerLocation {
     // https://html.spec.whatwg.org/multipage/#dom-workerlocation-hash
     fn Hash(&self) -> USVString {
         UrlHelper::Hash(&self.url)
diff --git a/components/script/dom/workernavigator.rs b/components/script/dom/workernavigator.rs
index 795c764b8c68e..b2c84137fce0e 100644
--- a/components/script/dom/workernavigator.rs
+++ b/components/script/dom/workernavigator.rs
@@ -39,7 +39,7 @@ impl WorkerNavigator {
     }
 }
 
-impl WorkerNavigatorMethods for WorkerNavigator {
+impl WorkerNavigatorMethods<crate::DomTypeHolder> for WorkerNavigator {
     // https://html.spec.whatwg.org/multipage/#dom-navigator-product
     fn Product(&self) -> DOMString {
         navigatorinfo::Product()
diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs
index ae6f677752336..2a9058ca9a18a 100644
--- a/components/script/dom/worklet.rs
+++ b/components/script/dom/worklet.rs
@@ -116,7 +116,7 @@ impl Worklet {
     }
 }
 
-impl WorkletMethods for Worklet {
+impl WorkletMethods<crate::DomTypeHolder> for Worklet {
     /// <https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule>
     fn AddModule(
         &self,
diff --git a/components/script/dom/xmldocument.rs b/components/script/dom/xmldocument.rs
index 627e0427a6ad8..a242d113a33b7 100644
--- a/components/script/dom/xmldocument.rs
+++ b/components/script/dom/xmldocument.rs
@@ -96,7 +96,7 @@ impl XMLDocument {
     }
 }
 
-impl XMLDocumentMethods for XMLDocument {
+impl XMLDocumentMethods<crate::DomTypeHolder> for XMLDocument {
     // https://html.spec.whatwg.org/multipage/#dom-document-location
     fn GetLocation(&self) -> Option<DomRoot<Location>> {
         self.upcast::<Document>().GetLocation()
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index da2cffe4cb6a8..24ba2586ed360 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -307,7 +307,7 @@ impl XMLHttpRequest {
     }
 }
 
-impl XMLHttpRequestMethods for XMLHttpRequest {
+impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
     /// <https://xhr.spec.whatwg.org/#constructors>
     fn Constructor(
         global: &GlobalScope,
diff --git a/components/script/dom/xmlhttprequesteventtarget.rs b/components/script/dom/xmlhttprequesteventtarget.rs
index af33da13b0c27..3cbc648c6f04b 100644
--- a/components/script/dom/xmlhttprequesteventtarget.rs
+++ b/components/script/dom/xmlhttprequesteventtarget.rs
@@ -20,7 +20,7 @@ impl XMLHttpRequestEventTarget {
     }
 }
 
-impl XMLHttpRequestEventTargetMethods for XMLHttpRequestEventTarget {
+impl XMLHttpRequestEventTargetMethods<crate::DomTypeHolder> for XMLHttpRequestEventTarget {
     // https://xhr.spec.whatwg.org/#handler-xhr-onloadstart
     event_handler!(loadstart, GetOnloadstart, SetOnloadstart);
 
diff --git a/components/script/dom/xmlserializer.rs b/components/script/dom/xmlserializer.rs
index 948c9013feacb..f9d616ebf10d5 100644
--- a/components/script/dom/xmlserializer.rs
+++ b/components/script/dom/xmlserializer.rs
@@ -43,7 +43,7 @@ impl XMLSerializer {
     }
 }
 
-impl XMLSerializerMethods for XMLSerializer {
+impl XMLSerializerMethods<crate::DomTypeHolder> for XMLSerializer {
     // https://w3c.github.io/DOM-Parsing/#dom-xmlserializer
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/xrboundedreferencespace.rs b/components/script/dom/xrboundedreferencespace.rs
index 87c267152c189..1434e23e6e17b 100644
--- a/components/script/dom/xrboundedreferencespace.rs
+++ b/components/script/dom/xrboundedreferencespace.rs
@@ -65,7 +65,7 @@ impl XRBoundedReferenceSpace {
     }
 }
 
-impl XRBoundedReferenceSpaceMethods for XRBoundedReferenceSpace {
+impl XRBoundedReferenceSpaceMethods<crate::DomTypeHolder> for XRBoundedReferenceSpace {
     /// <https://www.w3.org/TR/webxr/#dom-xrboundedreferencespace-boundsgeometry>
     fn BoundsGeometry(&self, cx: JSContext, can_gc: CanGc, retval: MutableHandleValue) {
         if let Some(bounds) = self.reference_space.get_bounds() {
diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs
index bda3cfea9789d..f3a8a263fd30f 100644
--- a/components/script/dom/xrframe.rs
+++ b/components/script/dom/xrframe.rs
@@ -75,7 +75,7 @@ impl XRFrame {
     }
 }
 
-impl XRFrameMethods for XRFrame {
+impl XRFrameMethods<crate::DomTypeHolder> for XRFrame {
     /// <https://immersive-web.github.io/webxr/#dom-xrframe-session>
     fn Session(&self) -> DomRoot<XRSession> {
         DomRoot::from_ref(&self.session)
diff --git a/components/script/dom/xrhand.rs b/components/script/dom/xrhand.rs
index 8362cda4d869b..b73e9cddb3558 100644
--- a/components/script/dom/xrhand.rs
+++ b/components/script/dom/xrhand.rs
@@ -134,7 +134,7 @@ impl XRHand {
     }
 }
 
-impl XRHandMethods for XRHand {
+impl XRHandMethods<crate::DomTypeHolder> for XRHand {
     /// <https://github.com/immersive-web/webxr-hands-input/blob/master/explainer.md>
     fn Size(&self) -> u32 {
         XRHandJoint::Pinky_finger_tip as u32 + 1
diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs
index abbb65bdc9b46..c7155d343d279 100644
--- a/components/script/dom/xrinputsource.rs
+++ b/components/script/dom/xrinputsource.rs
@@ -120,7 +120,7 @@ impl XRInputSource {
     }
 }
 
-impl XRInputSourceMethods for XRInputSource {
+impl XRInputSourceMethods<crate::DomTypeHolder> for XRInputSource {
     /// <https://immersive-web.github.io/webxr/#dom-xrinputsource-handedness>
     fn Handedness(&self) -> XRHandedness {
         match self.info.handedness {
diff --git a/components/script/dom/xrinputsourcearray.rs b/components/script/dom/xrinputsourcearray.rs
index be9e5ab78ddbb..18059db822a13 100644
--- a/components/script/dom/xrinputsourcearray.rs
+++ b/components/script/dom/xrinputsourcearray.rs
@@ -136,7 +136,7 @@ impl XRInputSourceArray {
     }
 }
 
-impl XRInputSourceArrayMethods for XRInputSourceArray {
+impl XRInputSourceArrayMethods<crate::DomTypeHolder> for XRInputSourceArray {
     /// <https://immersive-web.github.io/webxr/#dom-xrinputsourcearray-length>
     fn Length(&self) -> u32 {
         self.input_sources.borrow().len() as u32
diff --git a/components/script/dom/xrinputsourceevent.rs b/components/script/dom/xrinputsourceevent.rs
index 701b5d26cb889..cc694f8f99cc4 100644
--- a/components/script/dom/xrinputsourceevent.rs
+++ b/components/script/dom/xrinputsourceevent.rs
@@ -78,7 +78,7 @@ impl XRInputSourceEvent {
     }
 }
 
-impl XRInputSourceEventMethods for XRInputSourceEvent {
+impl XRInputSourceEventMethods<crate::DomTypeHolder> for XRInputSourceEvent {
     // https://immersive-web.github.io/webxr/#dom-xrinputsourceevent-xrinputsourceevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/xrinputsourceschangeevent.rs b/components/script/dom/xrinputsourceschangeevent.rs
index 1ae14b3a47c60..4429f7d545e8c 100644
--- a/components/script/dom/xrinputsourceschangeevent.rs
+++ b/components/script/dom/xrinputsourceschangeevent.rs
@@ -96,7 +96,7 @@ impl XRInputSourcesChangeEvent {
     }
 }
 
-impl XRInputSourcesChangeEventMethods for XRInputSourcesChangeEvent {
+impl XRInputSourcesChangeEventMethods<crate::DomTypeHolder> for XRInputSourcesChangeEvent {
     // https://immersive-web.github.io/webxr/#dom-xrinputsourceschangeevent-xrinputsourceschangeevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/xrjointpose.rs b/components/script/dom/xrjointpose.rs
index 9a3e60bab33c9..9d1ed30148696 100644
--- a/components/script/dom/xrjointpose.rs
+++ b/components/script/dom/xrjointpose.rs
@@ -43,7 +43,7 @@ impl XRJointPose {
     }
 }
 
-impl XRJointPoseMethods for XRJointPose {
+impl XRJointPoseMethods<crate::DomTypeHolder> for XRJointPose {
     /// <https://immersive-web.github.io/webxr/#dom-XRJointPose-views>
     fn GetRadius(&self) -> Option<Finite<f32>> {
         self.radius.map(Finite::wrap)
diff --git a/components/script/dom/xrjointspace.rs b/components/script/dom/xrjointspace.rs
index 36771f289b9c9..8d8dc9309f777 100644
--- a/components/script/dom/xrjointspace.rs
+++ b/components/script/dom/xrjointspace.rs
@@ -75,7 +75,7 @@ impl XRJointSpace {
     }
 }
 
-impl XRJointSpaceMethods for XRJointSpace {
+impl XRJointSpaceMethods<crate::DomTypeHolder> for XRJointSpace {
     /// <https://www.w3.org/TR/webxr-hand-input-1/#xrjointspace-jointname>
     fn JointName(&self) -> XRHandJoint {
         self.hand_joint
diff --git a/components/script/dom/xrlayerevent.rs b/components/script/dom/xrlayerevent.rs
index 763c9245903a9..136aac8745089 100644
--- a/components/script/dom/xrlayerevent.rs
+++ b/components/script/dom/xrlayerevent.rs
@@ -48,7 +48,7 @@ impl XRLayerEvent {
     }
 }
 
-impl XRLayerEventMethods for XRLayerEvent {
+impl XRLayerEventMethods<crate::DomTypeHolder> for XRLayerEvent {
     // https://immersive-web.github.io/layers/#dom-xrlayerevent-xrlayerevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/xrmediabinding.rs b/components/script/dom/xrmediabinding.rs
index 214d0e31d0e2c..14eec1fb354c5 100644
--- a/components/script/dom/xrmediabinding.rs
+++ b/components/script/dom/xrmediabinding.rs
@@ -47,7 +47,7 @@ impl XRMediaBinding {
     }
 }
 
-impl XRMediaBindingMethods for XRMediaBinding {
+impl XRMediaBindingMethods<crate::DomTypeHolder> for XRMediaBinding {
     /// <https://immersive-web.github.io/layers/#dom-xrmediabinding-xrmediabinding>
     fn Constructor(
         global: &Window,
diff --git a/components/script/dom/xrpose.rs b/components/script/dom/xrpose.rs
index be82e52c1a6c3..dea8aa62dc413 100644
--- a/components/script/dom/xrpose.rs
+++ b/components/script/dom/xrpose.rs
@@ -38,7 +38,7 @@ impl XRPose {
     }
 }
 
-impl XRPoseMethods for XRPose {
+impl XRPoseMethods<crate::DomTypeHolder> for XRPose {
     /// <https://immersive-web.github.io/webxr/#dom-xrpose-transform>
     fn Transform(&self) -> DomRoot<XRRigidTransform> {
         DomRoot::from_ref(&self.transform)
diff --git a/components/script/dom/xrray.rs b/components/script/dom/xrray.rs
index 52be024a0271f..d80a4c00d61ac 100644
--- a/components/script/dom/xrray.rs
+++ b/components/script/dom/xrray.rs
@@ -53,7 +53,7 @@ impl XRRay {
     }
 }
 
-impl XRRayMethods for XRRay {
+impl XRRayMethods<crate::DomTypeHolder> for XRRay {
     /// <https://immersive-web.github.io/hit-test/#dom-xrray-xrray>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/xrreferencespace.rs b/components/script/dom/xrreferencespace.rs
index 05b1d1c563687..6f8c409edbc2c 100644
--- a/components/script/dom/xrreferencespace.rs
+++ b/components/script/dom/xrreferencespace.rs
@@ -79,7 +79,7 @@ impl XRReferenceSpace {
     }
 }
 
-impl XRReferenceSpaceMethods for XRReferenceSpace {
+impl XRReferenceSpaceMethods<crate::DomTypeHolder> for XRReferenceSpace {
     /// <https://immersive-web.github.io/webxr/#dom-xrreferencespace-getoffsetreferencespace>
     fn GetOffsetReferenceSpace(&self, new: &XRRigidTransform, can_gc: CanGc) -> DomRoot<Self> {
         let offset = new.transform().then(&self.offset.transform());
diff --git a/components/script/dom/xrreferencespaceevent.rs b/components/script/dom/xrreferencespaceevent.rs
index e31c1da090345..e75aabe14a1d1 100644
--- a/components/script/dom/xrreferencespaceevent.rs
+++ b/components/script/dom/xrreferencespaceevent.rs
@@ -81,7 +81,7 @@ impl XRReferenceSpaceEvent {
     }
 }
 
-impl XRReferenceSpaceEventMethods for XRReferenceSpaceEvent {
+impl XRReferenceSpaceEventMethods<crate::DomTypeHolder> for XRReferenceSpaceEvent {
     /// <https://www.w3.org/TR/webxr/#dom-xrreferencespaceevent-xrreferencespaceevent>
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/xrrenderstate.rs b/components/script/dom/xrrenderstate.rs
index e189710ead287..cf6976404d680 100644
--- a/components/script/dom/xrrenderstate.rs
+++ b/components/script/dom/xrrenderstate.rs
@@ -124,7 +124,7 @@ impl XRRenderState {
     }
 }
 
-impl XRRenderStateMethods for XRRenderState {
+impl XRRenderStateMethods<crate::DomTypeHolder> for XRRenderState {
     /// <https://immersive-web.github.io/webxr/#dom-xrrenderstate-depthnear>
     fn DepthNear(&self) -> Finite<f64> {
         Finite::wrap(self.depth_near.get())
diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs
index 85849fe7f8022..fda4332eb0b62 100644
--- a/components/script/dom/xrrigidtransform.rs
+++ b/components/script/dom/xrrigidtransform.rs
@@ -72,7 +72,7 @@ impl XRRigidTransform {
     }
 }
 
-impl XRRigidTransformMethods for XRRigidTransform {
+impl XRRigidTransformMethods<crate::DomTypeHolder> for XRRigidTransform {
     // https://immersive-web.github.io/webxr/#dom-xrrigidtransform-xrrigidtransform
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs
index 6ba00e003a760..3bbe6537bb9ab 100644
--- a/components/script/dom/xrsession.rs
+++ b/components/script/dom/xrsession.rs
@@ -619,7 +619,7 @@ impl XRSession {
     }
 }
 
-impl XRSessionMethods for XRSession {
+impl XRSessionMethods<crate::DomTypeHolder> for XRSession {
     // https://immersive-web.github.io/webxr/#eventdef-xrsession-end
     event_handler!(end, GetOnend, SetOnend);
 
diff --git a/components/script/dom/xrsessionevent.rs b/components/script/dom/xrsessionevent.rs
index b253f7aa320fd..fda299a9f2ae8 100644
--- a/components/script/dom/xrsessionevent.rs
+++ b/components/script/dom/xrsessionevent.rs
@@ -68,7 +68,7 @@ impl XRSessionEvent {
     }
 }
 
-impl XRSessionEventMethods for XRSessionEvent {
+impl XRSessionEventMethods<crate::DomTypeHolder> for XRSessionEvent {
     // https://immersive-web.github.io/webxr/#dom-xrsessionevent-xrsessionevent
     fn Constructor(
         window: &Window,
diff --git a/components/script/dom/xrsubimage.rs b/components/script/dom/xrsubimage.rs
index e16e18bbaf277..53d2e3ca697b1 100644
--- a/components/script/dom/xrsubimage.rs
+++ b/components/script/dom/xrsubimage.rs
@@ -15,7 +15,7 @@ pub struct XRSubImage {
     viewport: Dom<XRViewport>,
 }
 
-impl XRSubImageMethods for XRSubImage {
+impl XRSubImageMethods<crate::DomTypeHolder> for XRSubImage {
     /// <https://immersive-web.github.io/layers/#dom-xrsubimage-viewport>
     fn Viewport(&self) -> DomRoot<XRViewport> {
         DomRoot::from_ref(&self.viewport)
diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs
index d6b3ed259d204..21705357e0b0b 100644
--- a/components/script/dom/xrsystem.rs
+++ b/components/script/dom/xrsystem.rs
@@ -110,7 +110,7 @@ impl From<XRSessionMode> for SessionMode {
     }
 }
 
-impl XRSystemMethods for XRSystem {
+impl XRSystemMethods<crate::DomTypeHolder> for XRSystem {
     /// <https://immersive-web.github.io/webxr/#dom-xr-issessionsupported>
     fn IsSessionSupported(&self, mode: XRSessionMode, can_gc: CanGc) -> Rc<Promise> {
         // XXXManishearth this should select an XR device first
diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs
index 275735733f89a..b1ef9596401ad 100644
--- a/components/script/dom/xrview.rs
+++ b/components/script/dom/xrview.rs
@@ -87,7 +87,7 @@ impl XRView {
     }
 }
 
-impl XRViewMethods for XRView {
+impl XRViewMethods<crate::DomTypeHolder> for XRView {
     /// <https://immersive-web.github.io/webxr/#dom-xrview-eye>
     fn Eye(&self) -> XREye {
         self.eye
diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs
index 9c8774c7855b5..47b166ab37535 100644
--- a/components/script/dom/xrviewerpose.rs
+++ b/components/script/dom/xrviewerpose.rs
@@ -188,7 +188,7 @@ impl XRViewerPose {
     }
 }
 
-impl XRViewerPoseMethods for XRViewerPose {
+impl XRViewerPoseMethods<crate::DomTypeHolder> for XRViewerPose {
     /// <https://immersive-web.github.io/webxr/#dom-xrviewerpose-views>
     fn Views(&self, _cx: JSContext, mut retval: MutableHandleValue) {
         retval.set(self.views.get())
diff --git a/components/script/dom/xrviewport.rs b/components/script/dom/xrviewport.rs
index 5a98c7839c040..8ac2851962004 100644
--- a/components/script/dom/xrviewport.rs
+++ b/components/script/dom/xrviewport.rs
@@ -31,7 +31,7 @@ impl XRViewport {
     }
 }
 
-impl XRViewportMethods for XRViewport {
+impl XRViewportMethods<crate::DomTypeHolder> for XRViewport {
     /// <https://immersive-web.github.io/webxr/#dom-xrviewport-x>
     fn X(&self) -> i32 {
         self.viewport.origin.x
diff --git a/components/script/dom/xrwebglbinding.rs b/components/script/dom/xrwebglbinding.rs
index 145937c022730..c2d652bb81d30 100644
--- a/components/script/dom/xrwebglbinding.rs
+++ b/components/script/dom/xrwebglbinding.rs
@@ -62,7 +62,7 @@ impl XRWebGLBinding {
     }
 }
 
-impl XRWebGLBindingMethods for XRWebGLBinding {
+impl XRWebGLBindingMethods<crate::DomTypeHolder> for XRWebGLBinding {
     /// <https://immersive-web.github.io/layers/#dom-xrwebglbinding-xrwebglbinding>
     fn Constructor(
         global: &Window,
diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs
index 3812c8df2ea27..031bd4b2f4d8c 100644
--- a/components/script/dom/xrwebgllayer.rs
+++ b/components/script/dom/xrwebgllayer.rs
@@ -237,7 +237,7 @@ impl XRWebGLLayer {
     }
 }
 
-impl XRWebGLLayerMethods for XRWebGLLayer {
+impl XRWebGLLayerMethods<crate::DomTypeHolder> for XRWebGLLayer {
     /// <https://immersive-web.github.io/webxr/#dom-xrwebgllayer-xrwebgllayer>
     fn Constructor(
         global: &Window,
diff --git a/components/script/dom/xrwebglsubimage.rs b/components/script/dom/xrwebglsubimage.rs
index 6a224e2583982..acdcd22f4a9f2 100644
--- a/components/script/dom/xrwebglsubimage.rs
+++ b/components/script/dom/xrwebglsubimage.rs
@@ -21,7 +21,7 @@ pub struct XRWebGLSubImage {
     size: Size2D<u32, Viewport>,
 }
 
-impl XRWebGLSubImageMethods for XRWebGLSubImage {
+impl XRWebGLSubImageMethods<crate::DomTypeHolder> for XRWebGLSubImage {
     /// <https://immersive-web.github.io/layers/#dom-xrwebglsubimage-colortexture>
     fn ColorTexture(&self) -> DomRoot<WebGLTexture> {
         DomRoot::from_ref(&self.color_texture)
diff --git a/components/script/lib.rs b/components/script/lib.rs
index 043f3fe2b4eaa..42f3d2c0c4c12 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -101,6 +101,8 @@ mod links;
 pub use init::init;
 pub use script_runtime::JSEngineSetup;
 
+pub use crate::dom::bindings::codegen::DomTypeHolder::DomTypeHolder;
+pub use crate::dom::bindings::codegen::DomTypes::DomTypes;
 // These trait exports are public, because they are used in the DOM bindings.
 // Since they are used in derive macros,
 // it is useful that they are accessible at the root of the crate.


Test patch:
diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs
index 1fc70eac60dbe..530544c97e120 100644
--- a/components/script/dom/testbinding.rs
+++ b/components/script/dom/testbinding.rs
@@ -81,7 +81,7 @@ impl TestBinding {
     }
 }
 
-impl TestBindingMethods for TestBinding {
+impl TestBindingMethods<crate::DomTypeHolder> for TestBinding {
     fn Constructor(
         global: &GlobalScope,
         proto: Option<HandleObject>,
diff --git a/components/script/dom/testbindingiterable.rs b/components/script/dom/testbindingiterable.rs
index 616d0296405c3..85fa46d2cb209 100644
--- a/components/script/dom/testbindingiterable.rs
+++ b/components/script/dom/testbindingiterable.rs
@@ -40,7 +40,7 @@ impl TestBindingIterable {
     }
 }
 
-impl TestBindingIterableMethods for TestBindingIterable {
+impl TestBindingIterableMethods<crate::DomTypeHolder> for TestBindingIterable {
     fn Constructor(
         global: &GlobalScope,
         proto: Option<HandleObject>,
diff --git a/components/script/dom/testbindingmaplike.rs b/components/script/dom/testbindingmaplike.rs
index f44f6aabd28d8..86b4c423939e7 100644
--- a/components/script/dom/testbindingmaplike.rs
+++ b/components/script/dom/testbindingmaplike.rs
@@ -46,7 +46,7 @@ impl TestBindingMaplike {
     }
 }
 
-impl TestBindingMaplikeMethods for TestBindingMaplike {
+impl TestBindingMaplikeMethods<crate::DomTypeHolder> for TestBindingMaplike {
     fn Constructor(
         global: &GlobalScope,
         proto: Option<HandleObject>,
diff --git a/components/script/dom/testbindingpairiterable.rs b/components/script/dom/testbindingpairiterable.rs
index 02febf599e3f1..8f11432d45a7c 100644
--- a/components/script/dom/testbindingpairiterable.rs
+++ b/components/script/dom/testbindingpairiterable.rs
@@ -60,7 +60,7 @@ impl TestBindingPairIterable {
     }
 }
 
-impl TestBindingPairIterableMethods for TestBindingPairIterable {
+impl TestBindingPairIterableMethods<crate::DomTypeHolder> for TestBindingPairIterable {
     fn Constructor(
         global: &GlobalScope,
         proto: Option<HandleObject>,
diff --git a/components/script/dom/testbindingproxy.rs b/components/script/dom/testbindingproxy.rs
index 55be0bfc28b37..4908d078bede3 100644
--- a/components/script/dom/testbindingproxy.rs
+++ b/components/script/dom/testbindingproxy.rs
@@ -15,7 +15,7 @@ pub struct TestBindingProxy {
     testbinding_: TestBinding,
 }
 
-impl TestBindingProxyMethods for TestBindingProxy {
+impl TestBindingProxyMethods<crate::DomTypeHolder> for TestBindingProxy {
     fn Length(&self) -> u32 {
         0
     }
diff --git a/components/script/dom/testbindingsetlike.rs b/components/script/dom/testbindingsetlike.rs
index 19db2a8d15442..3bf26c17f7f88 100644
--- a/components/script/dom/testbindingsetlike.rs
+++ b/components/script/dom/testbindingsetlike.rs
@@ -45,7 +45,7 @@ impl TestBindingSetlike {
     }
 }
 
-impl TestBindingSetlikeMethods for TestBindingSetlike {
+impl TestBindingSetlikeMethods<crate::DomTypeHolder> for TestBindingSetlike {
     fn Constructor(
         global: &GlobalScope,
         proto: Option<HandleObject>,
diff --git a/components/script/dom/testrunner.rs b/components/script/dom/testrunner.rs
index 9efd667350258..ae62777bab71d 100644
--- a/components/script/dom/testrunner.rs
+++ b/components/script/dom/testrunner.rs
@@ -36,7 +36,7 @@ impl TestRunner {
     }
 }
 
-impl TestRunnerMethods for TestRunner {
+impl TestRunnerMethods<crate::DomTypeHolder> for TestRunner {
     // https://webbluetoothcg.github.io/web-bluetooth/tests#setBluetoothMockDataSet
     #[allow(non_snake_case)]
     fn SetBluetoothMockDataSet(&self, dataSetName: DOMString) -> ErrorResult {
diff --git a/components/script/dom/testworklet.rs b/components/script/dom/testworklet.rs
index 9f3fa667590dc..b1589dd24f8ab 100644
--- a/components/script/dom/testworklet.rs
+++ b/components/script/dom/testworklet.rs
@@ -48,7 +48,7 @@ impl TestWorklet {
     }
 }
 
-impl TestWorkletMethods for TestWorklet {
+impl TestWorkletMethods<crate::DomTypeHolder> for TestWorklet {
     fn Constructor(
         window: &Window,
         proto: Option<HandleObject>,
diff --git a/components/script/dom/testworkletglobalscope.rs b/components/script/dom/testworkletglobalscope.rs
index 2540bc3141581..8e5597ba10eec 100644
--- a/components/script/dom/testworkletglobalscope.rs
+++ b/components/script/dom/testworkletglobalscope.rs
@@ -65,7 +65,7 @@ impl TestWorkletGlobalScope {
     }
 }
 
-impl TestWorkletGlobalScopeMethods for TestWorkletGlobalScope {
+impl TestWorkletGlobalScopeMethods<crate::DomTypeHolder> for TestWorkletGlobalScope {
     fn RegisterKeyValue(&self, key: DOMString, value: DOMString) {
         debug!("Registering test worklet key/value {}/{}.", key, value);
         self.lookup_table
diff --git a/components/script/dom/xrhittestresult.rs b/components/script/dom/xrhittestresult.rs
index eaed1ddb21c94..faca7dad3a31b 100644
--- a/components/script/dom/xrhittestresult.rs
+++ b/components/script/dom/xrhittestresult.rs
@@ -44,7 +44,7 @@ impl XRHitTestResult {
     }
 }
 
-impl XRHitTestResultMethods for XRHitTestResult {
+impl XRHitTestResultMethods<crate::DomTypeHolder> for XRHitTestResult {
     // https://immersive-web.github.io/hit-test/#dom-xrhittestresult-getpose
     fn GetPose(&self, base: &XRSpace, can_gc: CanGc) -> Option<DomRoot<XRPose>> {
         let base = self.frame.get_pose(base)?;
diff --git a/components/script/dom/xrhittestsource.rs b/components/script/dom/xrhittestsource.rs
index d816a4415db3a..5210bfa84a914 100644
--- a/components/script/dom/xrhittestsource.rs
+++ b/components/script/dom/xrhittestsource.rs
@@ -45,7 +45,7 @@ impl XRHitTestSource {
     }
 }
 
-impl XRHitTestSourceMethods for XRHitTestSource {
+impl XRHitTestSourceMethods<crate::DomTypeHolder> for XRHitTestSource {
     // https://immersive-web.github.io/hit-test/#dom-xrhittestsource-cancel
     fn Cancel(&self) {
         self.session.with_session(|s| s.cancel_hit_test(self.id));
diff --git a/components/script/dom/xrtest.rs b/components/script/dom/xrtest.rs
index 0f854ad38c66d..0117ab5c3cec0 100644
--- a/components/script/dom/xrtest.rs
+++ b/components/script/dom/xrtest.rs
@@ -66,7 +66,7 @@ impl XRTest {
     }
 }
 
-impl XRTestMethods for XRTest {
+impl XRTestMethods<crate::DomTypeHolder> for XRTest {
     /// <https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md>
     #[allow(unsafe_code)]
     fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit, can_gc: CanGc) -> Rc<Promise> {