- From: Dael Jackson <daelcss@gmail.com>
- Date: Sun, 9 Oct 2016 20:39:15 -0400
- To: public-houdini@w3.org
- Cc: www-style@w3.org
================================================= These are the official Houdini Task Force minutes. Unless you're correcting the minutes, please respond by starting a new thread with an appropriate subject line. ================================================= Typed OM -------- - RESOLVED: StyleValue must be immutable. - RESOLVED: Specified style map should be live. - RESOLVED: Computed style map is live. Stringification behavior ------------------------ - There were three options presented for what to stringify: 1) Minimal representation, which when reading it back it would be a different value than if you go through the old API. 2) Try and reproduce behavior of old OM (which wasn't consistent across browsers). 3) Always use source string. - RESOLVED: For computed style we'll use the minimal representation. This will give the same serialization as the CSSOM does for computed style when the values match. - A resolution wasn't reached for specified style, but the proposal was to re-serialize and pull out the string. CR for Paint ------------ - RESOLVED: Move global name resolution out of Paint level 1 to a future spec. - RESOLVED: Match canvas, transparent by default. - RESOLVED: Issue #1 resolved by matching properties/values syntax and adding input arguments. - RESOLVED: Paint API level 1 to CR (pending edits) Appropriate string representation to use in specified style ----------------------------------------------------------- - shane presented three options: 1. use string as-is 2. round-trip through CSS parser 3. minimal representation - There was a push to make sure that whatever approach is taken won't later become something we have to deal with for backwards compat. ===== FULL MINUTES BELOW ====== Agenda: https://github.com/w3c/css-houdini-drafts/wiki/TPAC-F2F-September-2016 Scribe: eae Typed OM ======== <dbaron> https://drafts.css-houdini.org/css-typed-om/ Should StyleValues be immutable? -------------------------------- shane: Two questions we couldn't resolve through issues on github that it would be good to have an answer for. shane: First up, "Should StyleValues be immutable?" shane: StyleValues are the values that are stored in the style map. Currently immutable. Cannot be changed, to update the value in the style map you have to create a new style value. I think this is the right solution but it is different from early assumptions. plinss: Difference between not being a live value and immutable. shane: One advantage of immutable is that it is obvious it is not live. dbaron: How do you make a new one? shane: Lots of constructors. shane: There are also parsers, from DOM Strings, for each type. So you could pass a Length type. dbaron: What does the parser look like in the spec? * shane presents the spec * dbaron: I see a from method on CSSLength dbaron: Some of the others don't have that. shane: We haven't finished it yet. TabAtkins: Everything will have a from. shane: There will be a from method on every subclass that takes a DOMString. shane: CSSStyleValue objects have a parse method which takes a property name and the string to parse. TabAtkins: The use case for this is to represent, as a css style value, anything we don't have a type for. Instead you can parse it with this and the value of it will be a cssvalue object. shane: Then there are more specific constructors for things like from(double value), from(Dictionary) etc shane: Lots of different ways to construct. Could have discussion about slimming that down. shane: Low cost of maintaining. plinss: What's the point of the dictionary? shane: Things like calc, takes a dictionary of values. TabAtkins: calc length stores as a sequence of just single unit values. If you want to do multiplication you have to do it on your own or do string parsing. Or use CSSLengthValue::multiple and friends. dbaron: There are a bunch of things that take a Sequence<CSSValue>. Can you have a Sequence of Sequences? TabAtkins: All are comma separated lists; one level. shane: We don't do things like transform. Doesn't make sense to consider first value of transform in isolation. Unlike background where the first value means something. dbaron: If you have something complicated as box shadow? TabAtkins: Would be a sequence of style values. Would be list of things where each thing represents a box shadow. shane: In the future there would be a box shadow type. dbaron: Is there a need for a definition of each type? TabAtkins: Not at the moment, needs to have some description. Opacity is easy, has one value, box shadow more complex. TabAtkins: If more complicated than a single value or comma separated list it would be represented by a style object. SimonSapin: There is one for each property? shane: There is a type for each grammar thing. TabAtkins: Right now we can only handle properties with a single production. TabAtkins: Eventually there will be things like a sequence of these types for box shadow. SimonSapin: Similar to have transition have specific text about it. TabAtkins: Yes. Specialized type that it would return. shane: Fundamentally quite similar. Rossen: Going back to the issue. shane: Question: Should these be immutable? shane: Anyone think otherwise? plinss: Not sure it's a bad idea; across the platform we have somethings that are live objects, some dead, some immutable. We should be consistent with the current trend wrt dead vs immutable. SimonSapin: Would sequences be immutable as well? TabAtkins: Yes, all attributes of things. shane: Can you make sequences immutable? TabAtkins: Frozen array? SimonSapin: Reconstruct each time? Is that easy? TabAtkins: Yes. SimonSapin: Okay. dbaron: I feel that there are a couple of things here being underspecified. TabAtkins: Yes, but hopefully not surprising. dbaron: How do you convert background position right 50% bottom 30px into an appropriate thing? TabAtkins: We potentially loose some detail from specified values. Would get a calc length that specifies something. dbaron: calc length assumes we would never extend the syntax. TabAtkins: Not necessarily, let's talk about it later. shane: We wanted to talk about stringification. Maybe we can leave that at overflow and get back to later. dino: Examples would be nice. TabAtkins: We describe positions as a set of calc offsets <TabAtkins> background-position: top 10px right 10px; <TabAtkins> ==> <TabAtkins> el.styleMap.get('background-position') <TabAtkins> CSSPositionVAlue(CSSSimpleLength(10, 'px'), CSSCalcLength({px: -10, percent: 100})) SimonSapin: If we get a value that can be either calc length or a value, how do you tell the type? TabAtkins: Check type of object. SimonSapin: How? TabAtkins: Using standard js syntax, instanceOf JakeA: With background position, right 0 is the right hand side of the image. Is that represented here? TabAtkins: Yes, would be a 100% which is also right aligned. shane: Reasonably happy it being immutable? RESOLVED: Style value must be immutable. How dead should the style maps be? ---------------------------------- <nainar> https://github.com/w3c/css-houdini-drafts/issues/149 shane: How dead is too dead. TabAtkins: When you pull a style map up, is the entire map dead or just the values? dbaron: The style map for specified style allows mutation. dbaron: You're asking whether to remove that? TabAtkins: We still need to be able to construct style maps appropriately [TabAtkins shows example from issue 149, comment from shane on Jul 27.] var map = el.styleMap; map.get('height') // for argument's sake, CSSSimpleLength(100, 'px') el.style.height = '200px'; map.get('height') // will still return CSSSimpleLength(100, 'px') shane: This seems strange, the computed style objects are not immutable. Having them be live is expensive? SimonSapin: Why would it be expensive? ojan: Would require style recalculation. dbaron: For gecko the non-live implementation for computed style would be easy. dbaron: In gecko when it changes style it get a new object. ojan: I think that matches the webkit and blink implementation. ojan: Computed style is cheap if it has already been computed. Non-live. ojan: Would be confusing for authors if it flushed style recalc. esprehn: Not sure how we wouldn't do that? esprehn: Need to resolve percentages? dbaron: Layout flushes. dbaron: getComputedStyle is live. SimonSapin: Depends on if you want computed values TabAtkins: Our intention is to use actual computed values, not resolved values. SimonSapin: So percentages stay that way. dbaron: One of the other question, does the style map get a flush? shane: I think it has to. dbaron: I think so too. gregwhitworth: So, what would that be in the example? 200px? ojan: Yes. dbaron: More complicated issue, if the element set style way before to 50px and here (line 2) you set it to 100px, If this line didn't flush it could still be 50px, or it flushed on line 2 and it's 100px, if it flushes later you might get 200 shane: How live is it? gregwhitworth: To me, when you called it, it should be computed before me it's what will be returned. TabAtkins: Flushed non-live? esprehn: If you want be non-live it should be a method. esprehn: .getStyleMap(), returns a new map every time. Ergonomics would be bad. esprehn: Would be hard, we lazy compute a lot. TabAtkins: Specified style should be live so you can set things? shane: So that you can set. ojan: We have element.styleMap is live, .getComputedStyleMap() is not a live thing. Has a snapshot problem. dbaron: Gecko doesn't have the snapshot problem. Most other implementations would. shane: Even across style updates? shane: What if I call element.getComputedStyleMap then do something to change it, is that reflect in the returned style map? esprehn: Yes, has to be, or we need to snapshot, which is expensive. esprehn: We do a lot lazily today, if we snapshot all lazily computed values must be computed at time of snapshot. Would be very expensive. We do it for limited things, alignment, user select etc. shane: I'm fine with it being live. ojan: I'm sad about it flushing style recalc on every getter gregwhitworth: We've been talking about this for two years. We want to fix it but not realistic. surma: What if make the developer specify the values they want? So that we don't have to compute all of them? ojan: Would make me happy. dbaron: Similar to having it be live. ojan: For user agents that already compute it would be similar. Much easier for other implementations. ojan: element.getComputedStyleMap('list of properties') SimonSapin: Isn't that the same as .get? ojan: You could call get 15 minutes from now. dbaron: I don't think users will understand what is expensive or not. esprehn: Only protecting you against flushes on the same element. Not sure that would save one from much. ojan: Quite common I feel. shane: Why not just move getComputedStyleValue? So that the element is the map for the computed value? <shane> element.getComputedStyleMap().get('height'); <shane> ^ NOOOOO <shane> element.getComputedStyleValue('height'); <shane> ^ \o/ ojan: Has same problem with interleaved read/writes. dbaron: The second one isn't that different from a live object. shane: Except the element is already live, we're not adding more live object. TabAtkins: Except it would still cause a flush for each ready if the developer isn't careful. shane: Idea of list of properties would be to return a guaranteed snapshot causing at most one flush. What's the downside? surma: List of properties. dbaron: A lot of work to avoid flushing, if that is what we want to avoid we should design for that explicitly. shane: Like a flag? avoidFlush? dbaron: Something like run this code without flushes with a callback? ojan: Can of worms. JakeA: Dom transactions kind of thing? iank: Yes, let's not get into that. JakeA: Making this API harder to deal with to try to solve dom transactions seems wrong TabAtkins: Three options. A) Live objects, B) Snapshot, expensive, C) snapshot for a few properties. ojan: Specified one should be live. No objections? Yay! RESOLVED: Specified style map should be live. [group votes for computed style map] <TabAtkins> C, then A <shane> A <surma> C > A <dbaron> A <eae> A <iank> NOT B <JakeA> A - but I don't know a ton about the problem <dino> C, but the API is very sucky so I don't like it. <nainar> A <Rossen> C <atotic> C <SimonSapin> A <iank> OMG NO WAIT! <ojan> what dino said! <dino> element.style.getComputedStyleMap('width').get('width') // yuck shane: No strong consensus. B can be ruled out. esprehn: Can we leave it as live for now? And then experiment with snapshotting? shane: Can I make a suggestion for C? <shane> element.style.getComputedStyleMap('width', 'height', '...') --> { width: ..., height: ...., } dino: Still seems really bad, element.style.getComputedStyleMap ('width', 'height', '...').width. Yick. <JakeA> const [width, height] = getComputedStylesThingy(['width', 'height']) <TabAtkins> JakeA: Or `const {width, height} = ...` shane: A it is. RESOLVED: Computed style map is live. We are all sad. shane: That is all for typed om. SimonSapin: Getters over attributes communicates that it is more expensive. Stringification behavior ======================== <eae> https://github.com/w3c/css-houdini-drafts/issues/268 shane: There are three different behaviors we could stringify. shane: First option is a minimal representation. Downside is that reading it back it would be a different value than if you go through the old API. shane: The second option would be to try to reproduce the behavior in the old OM. shane: It's not consistent across browsers. dbaron: Neither specified. shane: I don't want to do that UNLESS it comes straight from a stylesheet. Makes sense there. shane: Third option; always use the source string. shane: Currently speced is a combination of the three. Not ideal. We should pick one. shane: Would anyone object to always going with the minimal representation? dbaron: In a room full of implementors I don't think anyone is going to object. shane: Let's ask devrel? surma: I'd prefer numeric representation ojan: Need more examples. Rossen: What about colors? <shane> color: red; <shane> color: rgba(255, 0, 0, 1) ojan: Color is a good example of... depends on how you use it. eae: Helpful if you want to animate or manipulate it to get numeric value. ojan: Unexpected for authors. iank: I think rgb is OK. A lot of use cases are for quality testing. At least that is one use case. ojan: People do things like read out the value, if (color == 'red') etc. surma: but then they could skip the typed OM all together. aleks: Is there an option to do both? shane: Let's not do that. Rossen: When we're talking about css values, which are we talking about? Specified? Computed? Rossen: For computed there is no point in having original values (i.e. red). For specified on the other hand it makes a lot more sense. TabAtkins: You are proposing, values pulled out of stylesheets gets the parsed representation? Rossen: Right gregwhitworth: That is already not true. If you pull out color you get rgb. gregwhitworth: I don't want getComputedStyle to not return computed. Specified should stay specified. shane: We did this for color already, color names are aliases. Some browsers do it during parse. gregwhitworth: We should check with developers about use cases. shane: Keeping specified would be expensive. gregwhitworth: Don't we do that already for devtools? shane: Only with devtools open. shane: It's the most sane but I do not want to commit to it without investigation. Might be expensive or use a lot of extra memory. gregwhitworth: I feel like we need author feedback on this. shane: I think it's clear that we do not always want the minimal representation. shane: For computed style we DO want minimal. dbaron: Is this different from the minimal representation in getComputedStyle? ojan: This would not be resolved style. For width: auto you would get "auto". TabAtkins: Would only be different when the VALUES are different. shane: Serialization would be the same. RESOLVED: For computed style we'll use the minimal representation. This will give the same serialization as the CSSOM does for computed style when the values match. Rossen: Good! How about for specified? shane: There are again three cases. shane: We can't do anything for the first case, when you use a style value constructor. Minimal is only option. shane: Second case is using a parser, the most sensible options would be either minimal representation (same as for construct) or fateful string representation. TabAtkins: Minimal seems more consistent. shane: Would potentially change as you instantiate more types. shane: Without type we can only do the fateful representation, when we add type it would switch to minimal. TabAtkins: OM defines how to serialize. ojan: We're forced to use the string representation for types without an implementation. We don't want to change it when we add a new type. TabAtkins: OM already defines how to serialize, so we know how to do it. dbaron: Are we talking about computed or specified now? TabAtkins: Specified. <TabAtkins> CSSStyleVAlue.parse('box-shadow', "...") shane: Proposal re-serialize and pull out the string. ojan: Authors underestimate the memory overhead of keeping the strings. <dbaron> I think ojan convinced me that CSSStyleValue.parse() needs to serialize in specified values the same as things from a style sheet or a string-based setter -- but that doesn't necessarily apply to CSSLengthValue.from() <eae> dbaron++ esprehn: One of the key problems with things like rgb is that it's hard for developers to know what it is and do comparison. With typed om we're fixing that so that one can compare and determine that it's red. [break for lunch] Scribe: jet CR for Paint ============ Rossen: Let's go over open issues. iank: A few issues from bz, heycam review back in June. iank: 17 open issues in GitHub. iank: A lot are text fixups. Should registered paint names be limited to shadow trees they are in? --------------------------------------------------------------------- <nainar> https://github.com/w3c/css-houdini-drafts/issues/223 iank: non-editorial bug ^ esprehn: Global name resolution seems very hard. iank: Can move to CSS Paint API level 2 TabAtkins: We already treat animations this way (via inheritance) esprehn: Does it work with variables? esprehn: Would be nice to solve this for CSS globally RESOLVED: move out of Paint level 1 to a future spec Add "alpha" as an option ------------------------ iank: Issue 220. <nainar> https://github.com/w3c/css-houdini-drafts/issues/220 iank: Currently no alpha on an all-black canvas. ojan: If you know you're opaque you can optimize. TabAtkins: How about instead of alpha, you specify a BG color. TabAtkins: rgba color. TabAtkins: So we can paint something even when Paint callbacks aren't ready. iank: Currently we paint black on throws. TabAtkins: Default to transparent default image? TabAtkins: Before paint runs for the first time. dbaron: Even if default is opaque, if authors don't want that, people will turn off the optimization *anti-aliasing on opaque surfaces discussion ensues* iank: summary: what do we think about opaque by default? plinss: aka opt-in for alpha. JakeA: Canvas is transparent by default. surma: Opt-in is fine. surma: Can we match the behavior of having a transparent image by default? JakeA: We can have LCD anti-aliasing by default if opaque. ojan: I think this is true for all implementors who have LCD AA. surma: Matching canvas is desirable. <eae> having lcd aa with transparent backgrounds would require alpha per channel => a lot of extra memory. dbaron: Spec should mention both anti-aliasing of text and performance optimizations for things that are opaque. ojan: Background animated images occluded by transparency is a common use/perf hit. bz: Background size calls paint again? TabAtkins: yes RESOLVED: Match canvas, transparent by default RESOLVED: Issue #1 resolved by matching properties/values syntax and adding input arguments Rossen: Also add example for conic gradients RESOLVED: Paint API level 1 to CR (pending edits) Appropriate string representation to use in specified style =========================================================== shane: 1. use string as-is shane: 2. round-trip through CSS parser shane: 3. minimal representation shane: issue: which option to use? TabAtkins: Minimal representation can be safe but CSSOM may depend on things not represented TabAtkins: Probably safer to use as-is input string. TabAtkins: When we later add a box-shadow type, you'll get a minimal representation TabAtkins: for future types we can throw away the string. SimonSapin: Does this string get preserved after going through the style map? SimonSapin: Is this an exact string with whitespace/comments? TabAtkins: #1 preserves, #2 doesn't. TabAtkins: Better to retain a token stream? dbaron: Should test current implementations. shane: We resolved to not expose token streams in CSS. TabAtkins: Custom properties uses exact representation per CSS. TabAtkins: CSS.parse() preserves the original string TabAtkins: For memory, better to keep token stream or original string? esprehn: Give an example? TabAtkins: CSSStyleVale.parse(box-shadow: black) TabAtkins: Should we preserve the whitespace? esprehn: If we don't care about whitespace, save token stream. <TabAtkins> CSSStyleVAlue.parse('color', ' red') <TabAtkins> Does this give: <TabAtkins> 'red' <TabAtkins> or ' red' dbaron: We don't use token stream now, we use a typed value representation. dbaron: eg, specified style. dbaron: If you call CSSTRansformValue's constructor, then you get the specified style back, you need to construct a canonical string somehow dbaron: eg., for shadow: color, blur, x,y , spread. dbaron: If blur defaults to 0.0 you may omit it from the string. dbaron: Do you then use the constructAStringFromCSSStyleValue operation only when you call the constructor, or in other cases? dbaron: TabAtkins wants to use it in other cases. dbaron: Bad idea to use from shadowValue.parse() if we add properties later. dbaron: Currently records empty vs. zero dbaron: we may end up omitting or adding later. dbaron: We should follow CSSOM string generation rules though need better spec. <dbaron> or at least, we should unless we have a good reason to construct yet a different set of rules <esprehn> I'd prefer 'red', otherwise a CSSColorValue needs to have storage for the string <esprehn> trying to understand under what cases the space at the start matters <glazou> +1 to what esprehn said <glazou> esprehn: matters if you build a css-like language but still want to parse whitespace <TabAtkins> esprehn: It *probably doesn't* matter. I don't care about that. But the spaces stick around if we spec that you hold onto the original string. <TabAtkins> And they might not, if we spec that you just hold onto some value representation (probably token stream). <glazou> wait... <glazou> if we have a css parser <glazou> it should allow non-css languages based on css general syntax <Rossen> glazou, right, so you're agreeing we should keep the original input string <glazou> I agree that we should be able at least to detect there are leading ws <TabAtkins> glazou: That's a totes different topic. <glazou> one way or another <Rossen> glazou, agreed <glazou> in other terms, s* should be detected <glazou> FWIW, my jscssp parser preserves the original string on each construct *and* can detect ws and comments and report them individually TabAtkins: How about: if we build something out of a string, use CSSOM rules otherwise minimal representation. shane: This sounds horrible to implement. <shane> position: center center shane: In typed OM, I'd expect two length values 50% 50%. dbaron: Whatever we do today for specified style, let's use that and not make a new representation. shane: For typed OM center center isn't useful. dbaron: Typed OM should return 50% 50% but the style map should return what it does today. <TabAtkins> el.style.backgroundPosition = "center center"; print( el.styleMap.get("background-position") + ""); //yields "center center" <TabAtkins> Because print(el.style.backgroundPosition) also does. <esprehn> typedom CSSStyleValue today does: virtual String cssText() const { return toCSSValue()->cssText(); } <esprehn> so it converts to the old internal representation and returns that <TabAtkins> el.styleMap.set("background-position", CSSPositionValue.from("center center"); print( el.styleMap.get("background-position" + ""); // yields "center center" <TabAtkins> el.styleMap.set("background-position", CSSPositionValue (CSSLengthValue(50, "%"), CSSLengthValue(50, "%")); print(el.styleMap.get("background-position") + ""); // yields "50% 50%" dbaron: We wouldn't be here if we had types for all CSS values but we currently don't dbaron: but when we do, we shouldn't change and break backwards-compat. *chromium internals spoken here* <glazou> have you guys discussed access to the parser only or the lexer too ? <TabAtkins> glazou: Not yet. But look at https://github.com/WICG/CSS-Parser-API <glazou> thx TabAtkins <TabAtkins> glazou: Better: http://wicg.github.io/CSS-Parser-API/ <glazou> TabAtkins woah <gregwhitworth> http://jsbin.com/jupewavidi/edit?css,js,console,output <gregwhitworth> ^ testcase showing background-position TabAtkins: When we take a string straight to TypedOM without going thru the legacy system, do we reconstruct or return as-is? TabAtkins: if/when we change that CSSOM system, this will also change if we use the same system. Aleks: What is the use case for the string API?
Received on Monday, 10 October 2016 00:40:15 UTC