#674: HTMLScriptElement.supports(type) method

Visit on Github.

Opened Sep 6, 2021

Ya ya yawm TAG!

I'm requesting a TAG review of HTMLScriptElement.supports(type) method.

HTMLScriptElement.supports(type) method provides a unified way to detect new features that use script elements.

Further details:

  • I have reviewed the TAG's Web Platform Design Principles
  • Relevant time constraints or deadlines: I'd like to ship this feature by default in Chromium M97. Therefore, we hope that the review will be completed before the M97 branch cut date (November 4, 2021).
  • The group where the work on this specification is currently being done: WHATWG
  • The group where standardization of this work is intended to be done (if current group is a community group or other incubation venue):
  • Major unresolved issues with or opposition to this specification: None
  • This work is being funded by: Google

We'd prefer the TAG provide feedback as (please delete all but the desired option):

💬 leave review feedback as a comment in this issue and @-notify @horo-t

Discussions

Discussed Sep 1, 2021 (See Github)

Concerns about the method name being too generic for a limited use, gave feedback about renaming.

Transitioned the issue to in-progress and left comment

Comment by @LeaVerou Sep 6, 2021 (See Github)

Quick question: How is this detected today? Is this API proposing a nicer way to feature detect what values the type attribute supports, or is there no way to do feature detection for this today?

Comment by @horo-t Sep 7, 2021 (See Github)

This API is proposing a nicer and synchronous way to feature detect.

For module, we can use the nomodule attribute to detect the module type support as this example shows.

https://html.spec.whatwg.org/multipage/scripting.html#script-nomodule-example

<script type="module" src="app.mjs"></script>
<script nomodule defer src="classic-app-bundle.js"></script>

(Note: Safari 10 did support module, but didn't support nomodule. So we need some hack like this solution not to load <script nomodule>.)

For importmap, there is no synchronous way to detect the importmap type support. As described in the issue comment, we need to fetch an useless HTTP request.

https://github.com/WICG/import-maps/issues/171#issuecomment-521299519

<script type="importmap">
{
  "imports": {
    "vue": "/vendor/vue.js"
  }
}
</script>
// ...
<script>
import ("vue").catch(() => {
  // We'll get here if we're in a browser that doesn't support import maps,
  // because import "vue" will fail (with no evaluation performed). In that case
  // the <script type=module> was also a no-op (mostly).

  const s = document.createElement('script');
  s.src = "./bundle.js";
  document.body.append(s);
});
</script>
Comment by @atanassov Sep 14, 2021 (See Github)

@plinss and I looked at the proposal during our Gethen vf2f. The overall author simplification and improvement of the API over what they need to do today is certainly great.

One concern we have is they way the capability is to be exposed, the supports method. If this API was designed to check for any kind of support on the HTMLScriptElement then that would be fine, but you are restricting it to the type only. Perhaps you should consider exposing it as HTMLScriptElement.type.supports() (not sure if possible) or HTMLScriptElement.supportsType().

Comment by @horo-t Sep 14, 2021 (See Github)

I understand the concern. Changing the name to HTMLScriptElement.supportsType() sounds reasonable and feasible to me.

@domenic What do you think about it?

Comment by @domenic Sep 15, 2021 (See Github)

I kind of prefer the brevity and clarity of the existing method, and how it matches existing platform conventions (e.g. supports() on DOMTokenList or supports() on CSS). I don't know what other feature you would be detecting support for on HTMLScriptElement.

Comment by @LeaVerou Sep 15, 2021 (See Github)

I definitely see @domenic's point. I suppose if in the future we need to detect something else, there can be an optional second argument to supports() about what is being detected?

Comment by @plinss Sep 15, 2021 (See Github)

Our concern is due to the fact that the behavior is scoped to detecting supported values of type. Ideally, this would be expressed as script.type.supports('...'), but we accept the impracticality of getting that since type is a string.

Two alternate uses of HTMLScriptElement.supports() we came up with are: detecting JS features, e.g. script.supports('es2021'), or script.supports('await'), or a more generic script.supports('some random js code') (the latter would detect if everything is parseable without any execution); or collisions with a HTMLElement.supports() method that could be used to detect otherwise undetectable feature support on an element.

We did consider adding an argument to supports, e.g. script.supports('type', 'module'), but felt that was too early to define how alternative values would work.

Comment by @domenic Sep 15, 2021 (See Github)

Two alternate uses

These don't seems specific to HTMLScriptElement, but instead about JavaScript support in general. They would be best placed in another namespace, e.g. JavaScript.supports() like CSS.supports().

Comment by @plinss Sep 15, 2021 (See Github)

or collisions with a HTMLElement.supports() method that could be used to detect otherwise undetectable feature support on an element.

Comment by @domenic Sep 15, 2021 (See Github)

I don't understand why we would add anything to the HTMLElement base class, given that there are subclasses for all elements that have functionality.

Comment by @plinss Sep 15, 2021 (See Github)

For the reason I stated, as a general purpose supports mechanism, similar to CSS.supports() where results would be dependent on the element class, so a HTML.supports() wouldn't be appropriate.

Note that I'm not trying to design new features here, @atanassov and I are just asking the question "are there potential uses of a generic supports() method that have a different scope and may collide with this one", and I think the answer is, yes.

The bottom line is that while we can spend all day imagining (or denying) future uses, we just can't know what the future will bring. In general, using narrowly scoped features allows more flexibility down the road. If the goal here is brevity, I don't think saving 4 characters is worth the risk of future naming collisions which could lead to author confusion.

If your concern is more about being consistent with DOMTokenList.supports(), then that argues more for HTMLScriptElement.type.supports() than it does for HTMLScriptElement.supports().

Comment by @domenic Sep 15, 2021 (See Github)

OK. I guess we just have to agree to disagree.

Comment by @atanassov Sep 15, 2021 (See Github)

@domenic besides the brevity of the current name I don't see how the current proposal helps.

I kind of prefer the brevity and clarity of the existing method, and how it matches existing platform conventions (e.g. supports() on DOMTokenList or supports() on CSS).

As @plinss pointed out, this is precisely the confusing part with the current proposal because HTMLScriptElement.supports() is not intended to provide the generic capability CSS.supports() does. The fact that people recognize the API name will only add to the confusion as they realize that the only thing they can check for is type.

Comment by @domenic Sep 15, 2021 (See Github)

It provides the appropriately-scoped capability for the name. HTMLScriptElement.supports() is about what the HTML <script> element supports. If you want to check for JS feature support you should use a hypothetical JavaScript.supports().

Comment by @plinss Sep 15, 2021 (See Github)

But that’s just it, it doesn’t test what the script element supports, it tests what values of the type property the script element supports. What about when we want to add a test for values of another property?

Comment by @domenic Sep 15, 2021 (See Github)

It is my judgment as HTML editor that the most fundamental property of the script element is what types it supports. If, in some hypothetical (but in my judgment extremely unlikely) future there were some other property we'd want to test support for, we would add a new method named supportsX() for that, or an overload like supports("prop", "value"), and leave supports("value") for the most fundamental (and very likely only) thing that would be support-tested.

Discussed Sep 20, 2021 (See Github)

Rossen: Closed with comment

Comment by @annevk Sep 20, 2021 (See Github)

Also, most newer IDL attributes are limited to "known values", which means you can do feature testing without a dedicated method. That's generally the HTML way and what I would expect us to continue to use.

Comment by @atanassov Sep 21, 2021 (See Github)

@annevk and @domenic, thank you both for the engagement and feedback. It seems like we've exhausted the feedback on this particular issue on both sides. You have TAG's naming opinion and it is up to you what the final shape of it is. After all, our position is to provide advice and not force an opinion.

With that being said, the merit of the overall proposal is something we do like and want to see move forward, thus, closing the review. Thank you for working with us. Looking forward to your further progress.