If you haven't read through this thoroughly yet, please hold off. I have been working through the design and have discovered a number of issues. I am currently revising the approach and will send an updated email.
On Jul 16, 2010, at 11:35 AM, Greg Brown wrote: > This email is a bit long but I think it represents a good way to move the > styling discussion forward. Please read it if you are interested in this > discussion. > > I have been thinking about a way that we could support CSS either in addition > to or instead of JSON for styling. My original proposal for adding named > style support was something along these lines: > > <Window styleClasses="@my_styles.json" > xmlns:bxml="http://pivot.apache.org/bxml" > xmlns="org.apache.pivot.wtk"> > <BoxPane> > <Label styleClassNames="a, b, c" styles="{color:green; > font:Arial-BOLD-24}"/> > </BoxPane> > </Window> > > The "my_styles.json" file defines the (untyped) style classes "a", "b", and > "c". These would be applied when the "styleClassNames" attribute is > processed. The values in the "styles" attribute would then override any of > the styles defined by the style classes. > > However, this approach didn't work for two reasons: > > 1) Attributes aren't processed until the closing tag. This is by design - > consider a CardPane with a "selectedIndex" attribute. This value can't be set > until the card pane's children have been added. The implication here is that > the named styles specified by Window's "styleClasses" attribute won't be > loaded by the time the Label is created, so the named style classes won't be > found. > > 2) Child elements aren't added to the parent until the closing tag. So, even > if #1 is solved, Label won't be able to walk up the tree to find the named > styles because BoxPane wouldn't have been added to the Window yet. > > However, I believe I have a solution to both of these issues. I have already > modified BXMLSerializer to add child elements in the start tag, which > resolves #2. The resolution to #1 could be an annotation that specifies when > an attribute should be processed (e.g. @PostApply). If this attribute is not > specified, the attribute would be pre-applied (i.e. processed in the start > tag). > > Unfortunately, as we have discussed, another issue with this approach is that > JSON doesn't support namespaces. So it would be cumbersome to try to support > typed selectors in JSON. Typed selectors could be specified in WTKX, though: > > <Window > xmlns:bxml="http://pivot.apache.org/bxml" > xmlns="org.apache.pivot.wtk"> > <styleClasses> > <StyleClass type="org.apache.pivot.wtk.Label" name="a" > styles="{foo:'bar'}"/> > </styleClasses> > > <BoxPane> > <Label styleClassNames="a, b, c" styles="{color:green; > font:Arial-BOLD-24}"/> > </BoxPane> > </Window> > > Additionally, given CSS 3's proposed support for namespaces, it would become > possible to declare both typed and untyped selectors in an external CSS file. > WTK could also be updated to use inline CSS for local style specifications > vs. JSON, which would be slightly less verbose (no opening and closing curly > braces). > > <Window styleClasses="@my_styles.css" > xmlns:bxml="http://pivot.apache.org/bxml" > xmlns="org.apache.pivot.wtk"> > <BoxPane> > <Label styleClassNames="a, b, c" styles="color:green; > font:Arial-BOLD-24"/> > </BoxPane> > </Window> > > I think this approach would be much more intuitive than the current one. It > would also be more consistent, since all styling would be specified via CSS, > rather than by a combination of classpath, attribute, and page-level > variables. > > The changes required to support this feature include: > > 1) BXMLSerializer modifications discussed above (trivial, and nearly complete) > 2) Addition of a StyleClassSequence to Container (easy, but slightly > time-consuming) > 3) Addition of serialization support for loading stylesheets and processing > inline CSS > > #3 is obviously the most challenging. It will require implementing a new > serializer capable of processing CSS stylesheets: > > StylesheetSerializer : Serializer<StyleClass> > > An instance of this class would be used to process the "styleClasses" > attribute. It would probably also be used to process inline style > declarations, perhaps via a readStyleDeclaration(InputStream):Map<String, ?> > method. > > I don't think that implementing such a class will be very difficult. However, > as I mentioned earlier, I don't want to introduce a dependency on a 3rd party > library to support it. I'm not opposed to porting an existing implementation > that has a compatible license and including it in the platform, though. No > need to build it from scratch if there is already a good one we can use. > > One downside to moving to CSS for styling is the potential loss of support > for font encodings such as this: > > font: {bold:true} > > I don't think we'd want to mix this kind of JSON-oriented styling with CSS. > Instead, we'd want to support the CSS syntax: > > font-weight: bold > > This is doable - it just means that any skin that supports a "font" style > should also define setFontFamily(), setFontSize(), and setFontWeight() > methods. > > So, here is what I propose: I will make the necessary changes to > BXMLSerializer and Container that are required to support this. I will leave > the existing JSON-based style support in place for now (though I will > probably yank the classpath-based type selectors, since they will no longer > be necessary). CSS won't be supported, but developers will be able to define > and apply style classes in BXML as shown above. > > I would very much like to see support for CSS added, though. If anyone is > interested in working on the StylesheetSerializer class, please let me know. > I think it would make a great addition to the platform, and I would be highly > inclined to drop support for JSON styling in favor of CSS if this > functionality becomes available. > > Please let me know what you think. > > Thanks, > Greg >
