+ Background
We have slowly been moving toward creating a richer set of schema types and
adding a generalized mechanism for parsing/unparsing type values. We call this
system "Presentation Types" (taken from a feature of the same name in Symbolics
Dynamic Windows and Dylan DUIM). Basically, for each schema type, we define
methods for "accepting" from an external string representation into the
internal Javascript value and for "presenting" from an internal Javascript
value to an external string representation (this could be extended to
additional representations, e.g., json).
This system was first applied to solve a nagging issue in data-binding, where
attributes that were of type other than string did not behave properly when
data-bound. [For instance, data-binding a `boolean` value to `false` would try
to assign the string "false" to a Boolean and the implicit Javascript
conversion of the non-empty string to Boolean `true`! With the new system, the
type parser correctly accepts the string "false" into the internal Boolean
`false`.]
This system has been extended for CSS styling. All CSS property values are
represented as strings. When a CSS selector applies to a node, the attributes
corresponding to the applicable properties parse the CSS property value strings
into the appropriate attribute type. [For instance, styling an attribute of
type `color` to "rgb(255,0,0)" will correctly set the attribute to the internal
representation of red (0xff0000).]
Recently, we have added the ability for the debugger to understand Presentation
Types for attributes that have CSS bindings (we hope to extend it to all
attributes eventually). When inspecting an object with an attribute that has a
CSS `style` property, the debugger will represent the value of that attribute
as it would appear in a <stylesheet> (rather than simply printing out the
internal value, which may be inscrutable to the LZX programmer). As an
example, an attribute of type color, when inspected will look like:
> bgcolor:color red
displaying the schema type and the external representation of the value. For
developers, they can inspect the external value representation to see the
actual value that is stored:
> lzx> Debug.inspect(red)
> «color value#13| red» {
> value: 16711680
> }
> «color value#13| red»
> lzx>
We're pretty sure that `red` is a lot more user-friendly way to display the
color than `16711680`.
We are trying to compatibly introduce the use of this system throughout
OpenLaszlo, as we believe it is a very powerful mechanism. We hope to
eventually allow LZX programs to extend the schema type system for custom types
that may be needed for particular programs or features.
+ Question for the audience:
Currently, when one defines (or overrides) an attribute, you can specify a
default value:
<attribute name="bgcolor" style="background-color" value="..." />
In the past, the value `...` was inconsistently handled. For some types
(color, css, size), literals were parsed in the compiler to internal
representations, but expressions (e.g., constraints) were expected to yield the
correct internal value. For some attributes (fgcolor, bgcolor), special
setters try to guess whether they are being called with an external
representation or internal value and do the right thing. This system is really
a jury rig that has evolved over time, and the inconsistency is the source of a
lot of mystifying behavior and bugs.
I propose that we improve on the current system by introducing a _new_
attribute property `stylevalue` which will _always_ be an external
representation and hence always be parsed according to the attribute's type.
Thus, if I want to introduce a new type, say `image`, that could be a CSS-style
URL or color or gradient, I would be able to say:
<attribute name="background" style="background" type="image"
stylevalue="linear-gradient(center bottom, rgb(190,123,115) 31%,
rgb(228,160,150) 66%, rgb(255,192,180) 83%)" />
I chose the name `stylevalue` for this property, because I think most people
will encounter Presentation Types when working with <stylesheet>s and when
defining attributes that have a `style` property, indicating they can be
styled. Other ideas: `typevalue` (indicating the value is to be parsed by the
type), or `styledefault` (indicating the value is the default when there is no
applicable style), or, since this feature is not necessarily restricted to
stylable attributes, `typedefault` (a combination of the previous).
Your comments and ideas solicited.