- From: Shane Stephens <shans@google.com>
- Date: Mon, 10 Aug 2015 01:05:08 +0000
- To: "public-houdini@w3.org" <public-houdini@w3.org>
- Message-ID: <CAGTfzwSCiW6DOYCE3j6HxHgKO0AjR45aMMOQSECL3dyk1mqrJA@mail.gmail.com>
Hi houdiños, Being able to describe the type of CSS values has been an important part of the custom properties proposals that we've talked about in this group. I'd like to explore whether we can extend this notion to JavaScript - i.e. provide typed JS objects rather than strings when accessing custom CSS values. I'd also like to see whether we can retrofit the existing CSSOM with this idea. These ideas were discussed in the January f2f but I don't think we've talked about it much on list since. My reasons are basically those provided in Sydney: converting CSS strings to values is tedious, error-prone, and a source of performance problems. So to get the ball rolling - here's a partial proposal that only covers numbers and lengths. Obviously we'll eventually want to expose the rest of the types too, but we need to start somewhere :) Bikeshed away! (1) Access to typed CSSOM A new OM can't just start to replace existing CSSOM functionality with typed versions because this will break lots of things. Instead we should create a new interface, StylePropertyMap, that is accessible alongside the old methods: interface StyleValue { boolean isInitial(); boolean isInherit(); boolean isDefault(); boolean isUnset(); attribute DOMString cssString; } interface StylePropertyMap { StyleValue get(DOMString property); sequence<StyleValue> getAll(DOMString property); void set(DOMString property, StyleValue or sequence<StyleValue> or DOMString value); void append(DOMString property, StyleValue or sequence<StyleValue> or DOMString value); iterable<DOMString, StyleValue or DOMString>; stringifier; }; interface ComputedStylePropertyMap : StylePropertyMap { }; interface SpecifiedStylePropertyMap : StylePropertyMap { boolean has(DOMString property); sequence<DOMString> getProperties(); } partial interface Element { readonly attribute SpecifiedStylePropertyMap styleMap; }; partial interface Document { ComputedStylePropertyMap getComputedStyleMap(Element element); }; partial interface CSSStyleRule { readonly attribute SpecifiedStylePropertyMap styleMap; }; (2) Numbers Number properties like z-index or opacity should have a very simple wrapping: interface NumberValue : StyleValue { double value; } An open question: where and when does validation happen? What happens if I try to set an out-of-range number to opacity? Will this be consistent across all properties? (3) Lengths Usually, lengths are simple single-unit values (e.g. 50px or 30em). However, it is possible for calc values to be used instead. The following API tries to capture common use-cases without allowing web devs to accidentally write code that will break when calc values are fed in: enum LengthType { "px", "percent", "em", // ... } interface Length : StyleValue { Length add(Length value); // can throw Length subtract(Length value); // can throw Length multiply(double value); // can throw Length divide(double value); // can throw static Length parse(DOMString cssString); static Length fromValue(double value, LengthType type); static Length fromDictionary({...}); } [Constructor(DOMString cssString), Constructor(Length), Constructor({ // … all the props. })] interface CalcLength : Length { attribute double? px; attribute double? percent; attribute double? em; attribute double? ex; attribute double? ch; attribute double? rem; attribute double? vw; attribute double? vh; attribute double? vmin; attribute double? vmax; attribute double? cm; attribute double? mm; attribute double? q; attribute double? in; attribute double? pc; attribute double? pt; } // lengths that are *just* keywords don't become SimpleLengths or CalcLengths. interface SimpleLength : Length { attribute double value; readonly attribute LengthType type; } In particular, lengths can be manipulated using the Length API without knowing whether they're simple or calc expressions. One downside is that developers need to check whether a Length is a SimpleLength before extracting the Length value - but then again, in practice they should be doing this anyway. (4) Everything else I realize that there are lots of details missing! Hopefully there's enough here to kick off a conversation, though - is this a direction we want to go in, and does the API sketched out above look like it could work? Ideally, I'd like to either start incorporating some of this stuff in the CSS Properties and Values specification, or alternatively begin a new ED (CSSOM Level 2?) WDYT? Cheers, -Shane
Received on Monday, 10 August 2015 01:05:48 UTC