Currently, a control has a default style-class. For example, you can use 
.button in a style-sheet to style a Button. I propose to move the default 
style-class from the control to the skin (RT-32186). The impetus for this 
change is two-fold. 

Firstly, it can be argued that setting the style-class of a control should be 
left to the developer, that imposing a default style-class is implementation 
detail leaking into the public API. Moving the default style-class from the 
control to the skin addresses this concern.

The second motive has to do with CSS processing itself. When a skin is set on a 
control, the control adopts the styles of the skin and css is reapplied to the 
control in order to pick up the new styles. Thus, it takes two CSS passes to 
fully style a control. By moving the default style-class to the skin, the 
control no longer has to adopt the skin's styles. Styles still have to be 
applied to the skin, but this can be done from the skinProperty's invalidated 
method. These subtle changes - not adopting the styles and applying css to the 
skin from skinProperty's invalidated method - will simplify the code in 
Control.   

The reason for moving the default from Control to SkinBase and not Skin is that 
there is no API in Skin for getting style-class (or any other css selector 
attributes). Skin could implement the Styleable interface, but that would not 
be backward compatible. 

Another issue related to CSS processing has to do with looking up cached, 
matching styles for a node. When the skin is set on the node and adopts the 
styles of the skin, css is reapplied. This means that the css implementation 
will look for matching styles for the control. There is a map that has a node's 
simple class name, style-class, and id (the 'css selector' aspects of a node) 
as a key and the matching styles as a value. Since none of the 'css selector' 
aspects of the node have changed, the previously cached value is returned from 
the map. Then when the styles are applied to the node, css says 'oh, I've 
already calculated values for this kind of node' and doesn't bother looking up 
the properties that were added by the skin. This causes problems such as 
https://javafx-jira.kenai.com/browse/RT-31691.

The cache lookup issue can be resolved in other ways, such as adding the list 
of properties to the key, or adding a flag to cause css to calculate a value if 
there is no previously calculated value found. But I believe that moving the 
default style-class will lead to cleaner code.

If a control no longer adopts the skin's styles, then the control and the skin 
could be styled as separate entities. This would mean that instead of 

.tool-bar { -fx-orientation: vertical; -fx-spacing: 3; }

one would have to write 

ToolBar { -fx-orientation: vertical; } .tool-bar: { -fx-spacing: 3; }

since orientation is a property of ToolBar and spacing a property of 
ToolBarSkin. This is an issue for maintaining backward compatibility with 
existing stylesheets. This isn't a issue for caspian or modena but is for 
author style-sheets and inline styles. I have some ideas here, but all of them 
rather clunky and kludgey. My question on this point is whether or not this is 
a real concern. 


Reply via email to