w3c/css-houdini-drafts

[css-typed-om] How to deal with author-extensibility

tabatkins opened this issue · 2 comments

Currently, the Typed OM is not meant to be author-extensible. The style-setting functions only accept Typed OM classes, and tho theoretically you could subclass one of them, there's nothing defined that would give you any special behavior for doing so - you'd just be treated as the class you derived from.

There are several obvious places where author-extensibility would be really cool, however - custom colorspaces are a big one. We obviously don't want to harm our ability to add new stuff, but there should be ways to interact with the Typed OM that are still safe.

My first thought is to define that the functions that consume style objects can check for the presence of a converter function, and if it's defined, call that to convert it to a "real" Typed OM object. Like:

class XYZColor : CSSColorValue {
	constructor(x,y,z,alpha=1) { ... }
	toTypedOM() {
		const [l,a,b] = labFromXyz(this);
		return new CSSLab(l,a,b,this.alpha);
	}

This could also allow for defining new units in author space:

class Km : CSSUnitValue {
	constructor(value) { 
		this.value = value; 
		Object.defineProperty(this, "unit", {value:"km", writable:false});
	}
	toTypedOM() {
		return CSS.cm(this.value*100_000);
	}
}

The class would turn into a "real" Typed OM value fairly eagerly - a new length unit, for example, needs to be turned into a real CSS value immediately upon setting, so we know what it's CSS type is and can do math on it properly. But it would at least allow for custom stuff to be constructed and manipulated before it's merged into a "real" css structure.

Author extensibility is definitely important, though not sure about this API.
How would the implementation "collect" all the classes defined to inherit from CSSColorValue? Wouldn't you need some sort of registry?

Also note that you would need a from method as well, not just a to to be able to support the color space, and these need to produce/accept the same type.

How would the implementation "collect" all the classes defined to inherit from CSSColorValue? Wouldn't you need some sort of registry?

I'm not sure what you're referring to - could you elaborate?

As I described it, the impl wouldn't need to know anything - it would just check if the value has a .toTypedOM() method, and if it does, call it to get a "real" Typed OM value.

Also note that you would need a from method as well, not just a to to be able to support the color space, and these need to produce/accept the same type.

A "from" makes it bi-directional, which would mean the impl would need to know about the full set, and would involve a registry, yeah.

It's possible that doing this with more specialized registries is the way to go, rather than trying to make it generic; that might allow the values to persist as the custom class rather than being eagerly converted, too.

This requires more thought, clearly. ^_^