w3c / css-houdini-drafts

Mirror of https://hg.css-houdini.org/drafts
https://drafts.css-houdini.org/
Other
1.84k stars 141 forks source link

[css-typed-om] need to specify mappings between syntax, typed OM object tree, and underlying representation #718

Open dbaron opened 6 years ago

dbaron commented 6 years ago

In order for the Typed OM to be interoperable, I believe that mappings need to be specified between:

for both specified and computed values (except that some directions of the mapping don't need to be specified for computed values since they're readonly). (CSS should also specify the mapping from the underlying representation of the specified value to the underlying representation of the computed value, but that's not Typed OM's problem.)

This information is property-specific, so it needs to be specified for all properties (although many properties will share rules).

It's also not clear to me if the Typed OM spec is intended that the typed OM object tree is the underlying representation. There are certainly cases today where at least some browsers preserve distinctions that the Typed OM can't preserve, such as the + and - sign distinction in:

let body = document.body;
body.style.width = "calc(30em + -2e1px)";
body.style.height = "calc(30em - 200e-1px)";
console.log(body.getAttribute("style"));
// Firefox: width: calc(30em - 20px); height: calc(30em - 20px);
// Chrome: width: calc(30em + -20px); height: calc(30em - 20px);

I don't think the information in 5.8. List of CSS properties to their CSSStyleValue reification is anywhere near sufficient for this to be interoperable.

It would also be good if the spec were clear about whether its intent is that the Typed OM is the underlying representation; that would be important for reviewers of the specification.

tabatkins commented 6 years ago

It's also not clear to me if the Typed OM spec is intended that the typed OM object tree is the underlying representation.

It's not, the TypedOM form is meant to be equivalent to serialization - it's an input/output format that captures enough of the nuance, but the internal representation can be richer. I'll make it clearer.

I don't think the information in 5.8. List of CSS properties to their CSSStyleValue reification is anywhere near sufficient for this to be interoperable.

Correct, it's not. We're starting work on getting the list in the second half of that chapter filled in with more direct information.

tabatkins commented 6 years ago
  • string representations of values (input to parsing and output from serializing)
  • typed OM representations of values
  • the underlying representation of the values

I think what needs to be defined is:

"string -> underlying value" is just a CSS parse, not the responsibility of this spec. "string -> Typed OM" is always indirected thru the underlying value; we don't want to define an additional type of parsing. And as you say, "specified underlying -> computed underlying" is a badly-specified part of existing CSS, that @fantasai and I plan to fix at some point soonish.

tabatkins commented 6 years ago

On that note, does https://drafts.css-houdini.org/css-typed-om/#reify-property-style-value specify the "underlying value -> Typed OM" transformation to the level of detail you want?

bzbarsky commented 6 years ago

@tabatkins If typed OM is supposed to be a performance improvement over the author just pasting together strings and then calling a setter that parses, but is defined in terms of the implementation pasting together strings and then parsing that string... where is the performance improvement coming from?

tabatkins commented 6 years ago

??? I don't understand what you mean. In what way did I or the spec say anything about "pasting together strings and then parsing that string"?

bzbarsky commented 6 years ago

https://github.com/w3c/css-houdini-drafts/issues/718#issuecomment-368653186 doesn't mention a need to define "specified Typed OM -> Underlying specified values". So I assume the idea is that that translation is done via going to string and then back. If not, that translation needs to be defined.

tabatkins commented 6 years ago

Ah, right, I did indeed miss that in the listing. However, it's covered in the spec, tho with not enough detail yet - it's the "match a CSS grammar" algo.

bzbarsky commented 6 years ago

But specified values may not be the same thing as a grammar AST. In fact, so far they have just needed to be a something you could produce from a string and serialize to a string (and even this last may not be true for shorthands). I feel like there are assumptions being made here about what a "specified value" is that are not being spelled out and may well not match what implementations actually do. To the extent that implementations will need to change the concept of "specified value", the thing they need to change to needs to actually be specified.

tabatkins commented 6 years ago

Yeah, there's no assumption that specified values are a grammar AST. But you can read a grammar as applying to more than just strings (somewhat handwaved at the moment) - right now it's pretty trivial since you can only create single values, so there's no need to worry about how to interpret whitespace or anything.

(As I said, it's missing detail - this does need a less hand-waved description of how to interpret a CSS grammar against an object rather than a string.)

dbaron commented 6 years ago

(I'm still concerned about this issue in the context of w3ctag/design-reviews#223.)

tabatkins commented 6 years ago

So to review, we have a few ways to represent a value:

All three of these can represent specified or computed values, so six total.

We never actually go directly between strings and JS objects; we indirect thru CSS parsing into an underlying value, then reify that underlying value back up into a JS object. So the necessary linkages are 4: underlying -> string, string -> underlying, underlying -> object, object -> underlying.

The specified/computed split is handled by stating that the transformation of specifying => computed is only done in underlying values, and that's defined by CSS itself. When turning an underlying value to a string or object, the algorithms in the sections linked above distinguish between specified and computed values as appropriate. When going from string or object back to underlying value, you can only set specified values, so there's no need to worry about computed values.


So, to the best of my knowledge, the missing parts are just finishing out the lists in section 5.1 (underlying -> object) and 6.8 (underlying -> string) so that every single CSS property is defined, correct?

dbaron commented 6 years ago

I don't think it's OK to say that there are big missing parts that need to be defined by CSS in order for this spec to be implemented interoperably. Somebody needs to define those parts as part of making this spec stably implementable.

It's also not clear to me how Serialization from CSSOM Values defines the underlying → string; it's not clear from the introductory section that that's what it's defining, nor does it appear to have a clear model of what the underlying values are.

Likewise it's not clear to me how match a grammar defines the object → underlying mapping. Again, it's not clear what the model of the underlying values is.

(Historically the underlying computed values have been somewhat scoped by the "Computed value" lines, and the underlying specified values somewhat scoped when the serialization rules were clear about what did and didn't get normalized... but I don't think either is clearly defined.)