Developing CSSOM Value APIs for SVG / replacing SVGLength

This is addressing ACTION-3384.

At the f2f, we discussed better JS-oriented APIs for representing and
manipulating lengths, instead of just using strings like we do now.

Currently, the draft defines an SVGLength interface
<https://svgwg.org/svg2-draft/types.html#InterfaceSVGLength>.  I
argued at the f2f that this interface was unnecessarily clumsy and
Java-feeling, and that we should instead merge with the
CSS*ComponentValue interfaces that Anne van Kesteren started working
on before he left the CSSWG, and which we in the CSSWG will finish up
soonish.

That interface looks something like this:

[Constructor,
 Constructor(float value, DOMString unitType),
 Constructor(DOMString value)]
interface CSSLengthComponentValue {
  attribute float px;
  attribute float cm;
  attribute float mm;
  attribute float in;
  attribute float pt;
  attribute float pc;
  attribute float em;
  attribute float ex;
  attribute float ch;
  attribute float rem;
  attribute float vw;
  attribute float vh;
  attribute float vmin;
  attribute float vmax;
  attribute float percent;
  // and more as we add more units
  attribute DOMString valueAsString;
};

All of the unit attributes automatically interconvert - you can set
any of them and then read any other, and it'll automatically be the
value you just set, converted into the units you requested.  Similar
to SVGLength, each length can be associated with an element (for
resolving the relative units) and/or a length (for resolving
percentages).  If it's not associated with an appropriate thing, some
interconversions won't be possible, and the associated attributes will
instead be null.  For example:

// construct a naked object, so it's not associated with any element
var len = new CSSLengthComponentValue();
len.px = 20;
print(len.cm); // prints ".529167"
print(len.em); // prints "null"
print(len.percent); // prints "null"

The object remembers what type it was last set with, which it uses
when formatting its 'valueAsString' attribute.

Additionally, a number of much terser constructors are exposed on the
CSS object, one for each unit, so you can shorten the above example
to:

var len = CSS.px(20);
...

We're still left with the issue in the SVG2 draft of dealing with
conversions to/from percentages when the associated length is 0.  This
applies similarly to the v* units, when the associated viewport length
is 0.

Additional issue: do we need to explicitly handle the SVG
unitless-length thing?  I've never been completely clear over whether
that is the same as px or not.  If we do, what unit name should we
give it?  "user"?

Question: one of the motivations for doing this interface is to give
us a backdoor to reinvent the baseVal/animVal thing that authors tend
to hate.  I think we can do this cleanly by just making
SVGAnimatedLength inherit from CSSLengthComponentValue.  This way, you
could easily just to "el.x.px = 5" rather than having to do
"el.x.baseVal = '5px'" (though the latter is still possible, for
back-compat).  Does anyone see any problems with this?

~TJ

Received on Wednesday, 26 September 2012 00:33:32 UTC