-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Introduce attribute reflection extended attributes #11450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
A number of extended attributes are added which trigger IDL attribute reflection: - [Reflect] and [Reflect=string] cover basic content attribute reflection cases. - [ReflectURL] and [ReflectURL=string] covers reflection of USV attributes, which represent URLs. - [ReflectNonNegative] and [ReflectNonNegative=string] covers reflection of long attributes that should be limited to only non-negative numbers. - [ReflectPositive] and [ReflectPositive=string] covers reflection of double and unsigned long attributes which should be limited to positive numbers. - [ReflectPositiveWithFallback] and [ReflectPositiveWithFallback=string] covers reflection of double and unsigned long attributes which should be limited to positive numbers with fallback. Additionally: - [ReflectRange=(integer, integer)] can be used alongside others on unsigned long attributes that should be clamped to a range. - [ReflectDefault=number] can be used alongside others on double, long and unsigned long attributes that should be reflected with a default value.
I'm having a hard time reviewing this because, despite the bold text in the beginning, it seems to mix up the enumerated attribute handling into the same PR as the non-enumerated attribute work. |
Apologies I think it got changed by a build task after I updated it. If you look purely at the first commit it should be easy enough to review. I think I'll revert the enumerated stuff and move it to a separate tag on PR. |
I've dropped the second commit from this PR so it should be reviewable now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to start with [ReflectURL]
and take them in turns? I don't really know what @domenic would prefer so wait for him to say something, but I would find it easier if we did them incrementally.
To clarify you mean add a PR that does just I'm happy to split this however reviewers think is best. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this is quite impressive. The comprehensive updates to the prose and IDL are wonderful. I especially like the touch of adding the data-x
s to the string arguments so you link to the content attribute definitions.
In terms of splitting the PR, I think it would be reasonable to either do just [Reflect], or do [Reflect] and [ReflectURL], or do all of these at once. I don't think it will change the complexity of the review too much, and I don't feel strongly which path we take.
This specification text direction, which builds on top of and preserves the existing prose-based infrastructure, is different than what I was expecting. I was picturing that we would rebuild the specification to be centered around the extended attributes, getting rid of concepts like "reflected target", "reflected IDL attribute", "reflected content attribute", "treated as a URL", "limited to only positive numbers", etc. Instead we would do something like:
IDL attributes annotated with the [Reflect] content attribute have the following getter steps: [...] and the following setter steps: [...]
and then everything there would be phrased in terms of the IDL concepts, like the extended attribute arguments, the IDL attribute type, <span>this</span>
, or the presence of other auxiliary extended attributes.
I think my vision is cleaner, as it has fewer layers of abstraction. It also prevents people from attempting to do reflection in prose, which seems like a good idea. And it's closer to how one might implement these. However, it's certainly less incremental. What do you think?
So my thought process was to build this in a way that was as incremental as possible. Which is why it's currently in the form I've used. I don't know that we'll ever be able to fully get rid of spec prose for reflection, but it might be that the end situation has few enough special cases that their prose should just be rewritten to not mention reflection and then we could drop many of these existing concepts. My other hesitation along the same lines is I don't know what other specs use these algorithms. I didn't want to accidentally break URL reflection from another spec by removing the prose concept (though I'll admit it's rather vague at the moment so it's ideal anyway). I think my preference would be to write them in terms of the existing prose initially and then once we've moved everything across (including looking at other specs). We can possibly rewrite how they're defined to drop the old approach. It would be purely editorial (I guess normative because we're removing existing algorithms?). That way we don't break existing stuff and avoid duplication at the same time? One other question is are we aiming to go for 100% coverage in IDL. Or is it okay if we end up with some still defined manually. There's a number of odd cases that aren't currently possible to do in the IDL proposal.
The above is just some examples of what I've found, there's also the element internals cases that I haven't looked into yet and might need extra IDL or might not be doable. |
- Swap code for span - Add var to clampedMin and clampedMax - Correct plural
This is used to apply the reflection code only for the setter.
… instead of ReflectURL
… attribute, otherwise an integer, also clean up the single double usage to actually use a decimal.
Hopefully some of these changes improve the clarity of the definitions. I've also added a [ReflectSetter] as it turns out WebKit already has it and it cuts down on a number of basic setters. |
I was more hopeful that we'd be able to get rid of the spec prose. After your change, the only normative references I see to "reflect" are enumerated attributes, and the ones you list as not possible with IDL. But, see below for how keeping it might be the best way to make some of the existing cases more rigorous.
Personally, I think we should not be hesitant about breaking other such specs. The only other specs that should be using these concepts are:
I think this is fair. Even if we keep some prose concepts, I think it'd be nicer to clean up as much of the "public API" as possible. For example, getting rid of definitions like "default value" or "as a URL" or "limited to only non-negative numbers" and say that if you want those behaviors, you have to just use the extended attributes. (This could be done by having the algorithm steps inspect the reflected IDL attribute, instead of taking arguments.)
In my opinion, it's definitely fine to end up with some defined manually. I think the way they currently abuse "reflect" is not rigorous, and rewriting them to just be manual might be better. Or maybe the best road here is to figure out ways to define them rigorously using the prose concepts that underlie the extended attributes. (E.g., defining custom "get the element" algorithms for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me and I'd be OK merging it as-is.
One more potential point for discussion: we could automatically lowercase the name, to remove many cases where you need to provide it. E.g. instead of [Reflect="datetime"] attribute DOMString dateTime
, we could just do [Reflect] attribute DOMString dateTime
.
I kind of like the current explicitness, but on the other hand maintaining such cases is just kind of busywork for everyone, and maybe we should make it automatic. Then the string-taking versions is reserved for truly-exceptional cases.
<p>The <code data-x="xattr-ReflectDefault">[ReflectDefault]</code> <span>extended attribute</span> | ||
must only be used on attributes with a type of <code data-x="idl-double">double</code>, <code | ||
data-x="idl-long">long</code>, or <code data-x="idl-unsigned-long">unsigned long</code>. When used | ||
on an attribute of type <code data-x="idl-double">double</code>, it must take a decimal, otherwise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on an attribute of type <code data-x="idl-double">double</code>, it must take a decimal, otherwise | |
on an attribute of type <code data-x="idl-double">double</code>, it must take a decimal; otherwise |
|
||
<p>IDL attributes with the <code data-x="xattr-ReflectDefault">[ReflectDefault]</code> | ||
<span>extended attribute</span> have a <span>default value</span> provided by <code | ||
data-x="xattr-ReflectDefault">[ReflectDefault]</code>.</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provided by "the argument provided to" [ReflectDefault], or something like that?
Ah yeah the lowercasing was something I'd thought of too forgot to comment about it, it seems webkits does that automatically at the very least. I think I lean towards doing it automatically just because it cuts down on noise and then the string case as you say can be for stuff where it's genuinely a different name (think encoding reflecting enctype or I think there's some hyphenated ones dotted about) |
Since this has no normative impact, there's no need for browser support, just spec editor support. |
A number of extended attributes are added which trigger IDL attribute reflection:
[Reflect] and [Reflect=string] cover basic content attribute reflection cases.
[ReflectSetter] and [ReflectSetter=string] covers content attribute reflection only for setters.
[ReflectURL] and [ReflectURL=string] covers reflection of USV attributes, which represent URLs.
[ReflectNonNegative] and [ReflectNonNegative=string] covers reflection of long attributes that should be limited to only non-negative numbers.
[ReflectPositive] and [ReflectPositive=string] covers reflection of double and unsigned long attributes which should be limited to positive numbers.
[ReflectPositiveWithFallback] and [ReflectPositiveWithFallback=string] covers reflection of double and unsigned long attributes which should be limited to positive numbers with fallback.
Additionally:
[ReflectRange=(integer, integer)] can be used alongside others on unsigned long attributes that should be clamped to a range.
[ReflectDefault=number] can be used alongside others on double, long and unsigned long attributes that should be reflected with a default value.
Depends on: whatwg/webidl#1503
See #3238
(See WHATWG Working Mode: Changes for more details.)
/common-dom-interfaces.html ( diff )
/dom.html ( diff )
/edits.html ( diff )
/embedded-content-other.html ( diff )
/embedded-content.html ( diff )
/form-control-infrastructure.html ( diff )
/form-elements.html ( diff )
/forms.html ( diff )
/grouping-content.html ( diff )
/iframe-embed-object.html ( diff )
/image-maps.html ( diff )
/index.html ( diff )
/input.html ( diff )
/interaction.html ( diff )
/interactive-elements.html ( diff )
/media.html ( diff )
/obsolete.html ( diff )
/popover.html ( diff )
/scripting.html ( diff )
/semantics.html ( diff )
/tables.html ( diff )
/text-level-semantics.html ( diff )